1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | if (typeof jQuery === "undefined") {
|
21 | throw new Error("SlickGrid requires jquery module to be loaded");
|
22 | }
|
23 | if (!jQuery.fn.drag) {
|
24 | throw new Error("SlickGrid requires jquery.event.drag module to be loaded");
|
25 | }
|
26 | if (typeof Slick === "undefined") {
|
27 | throw new Error("slick.core.js not loaded");
|
28 | }
|
29 |
|
30 |
|
31 | (function ($) {
|
32 |
|
33 | $.extend(true, window, {
|
34 | Slick: {
|
35 | Grid: SlickGrid
|
36 | }
|
37 | });
|
38 |
|
39 |
|
40 | var scrollbarDimensions;
|
41 | var maxSupportedCssHeight;
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | |
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | function SlickGrid(container, data, columns, options) {
|
56 |
|
57 | var defaults = {
|
58 | alwaysShowVerticalScroll: false,
|
59 | explicitInitialization: false,
|
60 | rowHeight: 25,
|
61 | defaultColumnWidth: 80,
|
62 | enableAddRow: false,
|
63 | leaveSpaceForNewRows: false,
|
64 | editable: false,
|
65 | autoEdit: true,
|
66 | suppressActiveCellChangeOnEdit: false,
|
67 | enableCellNavigation: true,
|
68 | enableColumnReorder: true,
|
69 | asyncEditorLoading: false,
|
70 | asyncEditorLoadDelay: 100,
|
71 | forceFitColumns: false,
|
72 | enableAsyncPostRender: false,
|
73 | asyncPostRenderDelay: 50,
|
74 | enableAsyncPostRenderCleanup: false,
|
75 | asyncPostRenderCleanupDelay: 40,
|
76 | autoHeight: false,
|
77 | editorLock: Slick.GlobalEditorLock,
|
78 | showHeaderRow: false,
|
79 | headerRowHeight: 25,
|
80 | createFooterRow: false,
|
81 | showFooterRow: false,
|
82 | footerRowHeight: 25,
|
83 | createPreHeaderPanel: false,
|
84 | showPreHeaderPanel: false,
|
85 | preHeaderPanelHeight: 25,
|
86 | showTopPanel: false,
|
87 | topPanelHeight: 25,
|
88 | formatterFactory: null,
|
89 | editorFactory: null,
|
90 | cellFlashingCssClass: "flashing",
|
91 | selectedCellCssClass: "selected",
|
92 | multiSelect: true,
|
93 | enableTextSelectionOnCells: false,
|
94 | dataItemColumnValueExtractor: null,
|
95 | fullWidthRows: false,
|
96 | multiColumnSort: false,
|
97 | numberedMultiColumnSort: false,
|
98 | tristateMultiColumnSort: false,
|
99 | sortColNumberInSeparateSpan: false,
|
100 | defaultFormatter: defaultFormatter,
|
101 | forceSyncScrolling: false,
|
102 | addNewRowCssClass: "new-row",
|
103 | preserveCopiedSelectionOnPaste: false,
|
104 | showCellSelection: true,
|
105 | viewportClass: null,
|
106 | minRowBuffer: 3,
|
107 | emulatePagingWhenScrolling: true,
|
108 | editorCellNavOnLRKeys: false
|
109 | };
|
110 |
|
111 | var columnDefaults = {
|
112 | name: "",
|
113 | resizable: true,
|
114 | sortable: false,
|
115 | minWidth: 30,
|
116 | rerenderOnResize: false,
|
117 | headerCssClass: null,
|
118 | defaultSortAsc: true,
|
119 | focusable: true,
|
120 | selectable: true
|
121 | };
|
122 |
|
123 |
|
124 | var th;
|
125 | var h;
|
126 | var ph;
|
127 | var n;
|
128 | var cj;
|
129 |
|
130 | var page = 0;
|
131 | var offset = 0;
|
132 | var vScrollDir = 1;
|
133 |
|
134 |
|
135 | var initialized = false;
|
136 | var $container;
|
137 | var uid = "slickgrid_" + Math.round(1000000 * Math.random());
|
138 | var self = this;
|
139 | var $focusSink, $focusSink2;
|
140 | var $headerScroller;
|
141 | var $headers;
|
142 | var $headerRow, $headerRowScroller, $headerRowSpacer;
|
143 | var $footerRow, $footerRowScroller, $footerRowSpacer;
|
144 | var $preHeaderPanel, $preHeaderPanelScroller, $preHeaderPanelSpacer;
|
145 | var $topPanelScroller;
|
146 | var $topPanel;
|
147 | var $viewport;
|
148 | var $canvas;
|
149 | var $style;
|
150 | var $boundAncestors;
|
151 | var stylesheet, columnCssRulesL, columnCssRulesR;
|
152 | var viewportH, viewportW;
|
153 | var canvasWidth;
|
154 | var viewportHasHScroll, viewportHasVScroll;
|
155 | var headerColumnWidthDiff = 0, headerColumnHeightDiff = 0,
|
156 | cellWidthDiff = 0, cellHeightDiff = 0, jQueryNewWidthBehaviour = false;
|
157 | var absoluteColumnMinWidth;
|
158 |
|
159 | var tabbingDirection = 1;
|
160 | var activePosX;
|
161 | var activeRow, activeCell;
|
162 | var activeCellNode = null;
|
163 | var currentEditor = null;
|
164 | var serializedEditorValue;
|
165 | var editController;
|
166 |
|
167 | var rowsCache = {};
|
168 | var renderedRows = 0;
|
169 | var numVisibleRows;
|
170 | var prevScrollTop = 0;
|
171 | var scrollTop = 0;
|
172 | var lastRenderedScrollTop = 0;
|
173 | var lastRenderedScrollLeft = 0;
|
174 | var prevScrollLeft = 0;
|
175 | var scrollLeft = 0;
|
176 |
|
177 | var selectionModel;
|
178 | var selectedRows = [];
|
179 |
|
180 | var plugins = [];
|
181 | var cellCssClasses = {};
|
182 |
|
183 | var columnsById = {};
|
184 | var sortColumns = [];
|
185 | var columnPosLeft = [];
|
186 | var columnPosRight = [];
|
187 |
|
188 | var pagingActive = false;
|
189 | var pagingIsLastPage = false;
|
190 |
|
191 | var scrollThrottle = ActionThrottle(render, 50);
|
192 |
|
193 |
|
194 | var h_editorLoader = null;
|
195 | var h_render = null;
|
196 | var h_postrender = null;
|
197 | var h_postrenderCleanup = null;
|
198 | var postProcessedRows = {};
|
199 | var postProcessToRow = null;
|
200 | var postProcessFromRow = null;
|
201 | var postProcessedCleanupQueue = [];
|
202 | var postProcessgroupId = 0;
|
203 |
|
204 |
|
205 | var counter_rows_rendered = 0;
|
206 | var counter_rows_removed = 0;
|
207 |
|
208 |
|
209 |
|
210 | var rowNodeFromLastMouseWheelEvent;
|
211 | var zombieRowNodeFromLastMouseWheelEvent;
|
212 | var zombieRowCacheFromLastMouseWheelEvent;
|
213 | var zombieRowPostProcessedFromLastMouseWheelEvent;
|
214 |
|
215 |
|
216 | var cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };
|
217 | var $hiddenParents;
|
218 | var oldProps = [];
|
219 | var columnResizeDragging = false;
|
220 |
|
221 |
|
222 |
|
223 |
|
224 | function init() {
|
225 | if (container instanceof jQuery) {
|
226 | $container = container;
|
227 | } else {
|
228 | $container = $(container);
|
229 | }
|
230 | if ($container.length < 1) {
|
231 | throw new Error("SlickGrid requires a valid container, " + container + " does not exist in the DOM.");
|
232 | }
|
233 |
|
234 | cacheCssForHiddenInit();
|
235 |
|
236 |
|
237 | maxSupportedCssHeight = maxSupportedCssHeight || getMaxSupportedCssHeight();
|
238 |
|
239 | options = $.extend({}, defaults, options);
|
240 | validateAndEnforceOptions();
|
241 | columnDefaults.width = options.defaultColumnWidth;
|
242 |
|
243 | columnsById = {};
|
244 | for (var i = 0; i < columns.length; i++) {
|
245 | var m = columns[i] = $.extend({}, columnDefaults, columns[i]);
|
246 | columnsById[m.id] = i;
|
247 | if (m.minWidth && m.width < m.minWidth) {
|
248 | m.width = m.minWidth;
|
249 | }
|
250 | if (m.maxWidth && m.width > m.maxWidth) {
|
251 | m.width = m.maxWidth;
|
252 | }
|
253 | }
|
254 |
|
255 |
|
256 | if (options.enableColumnReorder && !$.fn.sortable) {
|
257 | throw new Error("SlickGrid's 'enableColumnReorder = true' option requires jquery-ui.sortable module to be loaded");
|
258 | }
|
259 |
|
260 | editController = {
|
261 | "commitCurrentEdit": commitCurrentEdit,
|
262 | "cancelCurrentEdit": cancelCurrentEdit
|
263 | };
|
264 |
|
265 | $container
|
266 | .empty()
|
267 | .css("overflow", "hidden")
|
268 | .css("outline", 0)
|
269 | .addClass(uid)
|
270 | .addClass("ui-widget");
|
271 |
|
272 |
|
273 | if (!/relative|absolute|fixed/.test($container.css("position"))) {
|
274 | $container.css("position", "relative");
|
275 | }
|
276 |
|
277 | $focusSink = $("<div tabIndex='0' hideFocus style='position:fixed;width:0;height:0;top:0;left:0;outline:0;'></div>").appendTo($container);
|
278 |
|
279 | if (options.createPreHeaderPanel) {
|
280 | $preHeaderPanelScroller = $("<div class='slick-preheader-panel ui-state-default' style='overflow:hidden;position:relative;' />").appendTo($container);
|
281 | $preHeaderPanel = $("<div />").appendTo($preHeaderPanelScroller);
|
282 | $preHeaderPanelSpacer = $("<div style='display:block;height:1px;position:absolute;top:0;left:0;'></div>")
|
283 | .appendTo($preHeaderPanelScroller);
|
284 |
|
285 | if (!options.showPreHeaderPanel) {
|
286 | $preHeaderPanelScroller.hide();
|
287 | }
|
288 | }
|
289 |
|
290 | $headerScroller = $("<div class='slick-header ui-state-default' />").appendTo($container);
|
291 | $headers = $("<div class='slick-header-columns' style='left:-1000px' />").appendTo($headerScroller);
|
292 |
|
293 | $headerRowScroller = $("<div class='slick-headerrow ui-state-default' />").appendTo($container);
|
294 | $headerRow = $("<div class='slick-headerrow-columns' />").appendTo($headerRowScroller);
|
295 | $headerRowSpacer = $("<div style='display:block;height:1px;position:absolute;top:0;left:0;'></div>")
|
296 | .appendTo($headerRowScroller);
|
297 |
|
298 | $topPanelScroller = $("<div class='slick-top-panel-scroller ui-state-default' />").appendTo($container);
|
299 | $topPanel = $("<div class='slick-top-panel' style='width:10000px' />").appendTo($topPanelScroller);
|
300 |
|
301 | if (!options.showTopPanel) {
|
302 | $topPanelScroller.hide();
|
303 | }
|
304 |
|
305 | if (!options.showHeaderRow) {
|
306 | $headerRowScroller.hide();
|
307 | }
|
308 |
|
309 | $viewport = $("<div class='slick-viewport' style='width:100%;overflow:auto;outline:0;position:relative;;'>").appendTo($container);
|
310 | $viewport.css("overflow-y", options.alwaysShowVerticalScroll ? "scroll" : (options.autoHeight ? "hidden" : "auto"));
|
311 | $viewport.css("overflow-x", options.forceFitColumns ? "hidden" : "auto");
|
312 | if (options.viewportClass) $viewport.toggleClass(options.viewportClass, true);
|
313 |
|
314 | $canvas = $("<div class='grid-canvas' />").appendTo($viewport);
|
315 |
|
316 | scrollbarDimensions = scrollbarDimensions || measureScrollbar();
|
317 |
|
318 | if ($preHeaderPanelSpacer) $preHeaderPanelSpacer.css("width", getCanvasWidth() + scrollbarDimensions.width + "px");
|
319 | $headers.width(getHeadersWidth());
|
320 | $headerRowSpacer.css("width", getCanvasWidth() + scrollbarDimensions.width + "px");
|
321 |
|
322 |
|
323 |
|
324 | if (options.createFooterRow) {
|
325 | $footerRowScroller = $("<div class='slick-footerrow ui-state-default' />").appendTo($container);
|
326 | $footerRow = $("<div class='slick-footerrow-columns' />").appendTo($footerRowScroller);
|
327 | $footerRowSpacer = $("<div style='display:block;height:1px;position:absolute;top:0;left:0;'></div>")
|
328 | .css("width", getCanvasWidth() + scrollbarDimensions.width + "px")
|
329 | .appendTo($footerRowScroller);
|
330 |
|
331 | if (!options.showFooterRow) {
|
332 | $footerRowScroller.hide();
|
333 | }
|
334 | }
|
335 |
|
336 | $focusSink2 = $focusSink.clone().appendTo($container);
|
337 |
|
338 | if (!options.explicitInitialization) {
|
339 | finishInitialization();
|
340 | }
|
341 | }
|
342 |
|
343 | function finishInitialization() {
|
344 | if (!initialized) {
|
345 | initialized = true;
|
346 |
|
347 | viewportW = parseFloat($.css($container[0], "width", true));
|
348 |
|
349 |
|
350 |
|
351 | measureCellPaddingAndBorder();
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 | disableSelection($headers);
|
359 |
|
360 | if (!options.enableTextSelectionOnCells) {
|
361 |
|
362 |
|
363 | $viewport.on("selectstart.ui", function (event) {
|
364 | return $(event.target).is("input,textarea");
|
365 | });
|
366 | }
|
367 |
|
368 | updateColumnCaches();
|
369 | createColumnHeaders();
|
370 | setupColumnSort();
|
371 | createCssRules();
|
372 | resizeCanvas();
|
373 | bindAncestorScrollEvents();
|
374 |
|
375 | $container
|
376 | .on("resize.slickgrid", resizeCanvas);
|
377 | $viewport
|
378 |
|
379 | .on("scroll", handleScroll);
|
380 | $headerScroller
|
381 |
|
382 | .on("contextmenu", handleHeaderContextMenu)
|
383 | .on("click", handleHeaderClick)
|
384 | .on("mouseenter", ".slick-header-column", handleHeaderMouseEnter)
|
385 | .on("mouseleave", ".slick-header-column", handleHeaderMouseLeave);
|
386 | $headerRowScroller
|
387 | .on("scroll", handleHeaderRowScroll);
|
388 |
|
389 | if (options.createFooterRow) {
|
390 | $footerRowScroller
|
391 | .on("scroll", handleFooterRowScroll);
|
392 | }
|
393 |
|
394 | if (options.createPreHeaderPanel) {
|
395 | $preHeaderPanelScroller
|
396 | .on("scroll", handlePreHeaderPanelScroll);
|
397 | }
|
398 |
|
399 | $focusSink.add($focusSink2)
|
400 | .on("keydown", handleKeyDown);
|
401 | $canvas
|
402 | .on("keydown", handleKeyDown)
|
403 | .on("click", handleClick)
|
404 | .on("dblclick", handleDblClick)
|
405 | .on("contextmenu", handleContextMenu)
|
406 | .on("draginit", handleDragInit)
|
407 | .on("dragstart", {distance: 3}, handleDragStart)
|
408 | .on("drag", handleDrag)
|
409 | .on("dragend", handleDragEnd)
|
410 | .on("mouseenter", ".slick-cell", handleMouseEnter)
|
411 | .on("mouseleave", ".slick-cell", handleMouseLeave);
|
412 |
|
413 |
|
414 | if (navigator.userAgent.toLowerCase().match(/webkit/) &&
|
415 | navigator.userAgent.toLowerCase().match(/macintosh/)) {
|
416 | $canvas.on("mousewheel", handleMouseWheel);
|
417 | }
|
418 | restoreCssFromHiddenInit();
|
419 | }
|
420 | }
|
421 |
|
422 | function cacheCssForHiddenInit() {
|
423 |
|
424 | $hiddenParents = $container.parents().addBack().not(':visible');
|
425 | $hiddenParents.each(function() {
|
426 | var old = {};
|
427 | for ( var name in cssShow ) {
|
428 | old[ name ] = this.style[ name ];
|
429 | this.style[ name ] = cssShow[ name ];
|
430 | }
|
431 | oldProps.push(old);
|
432 | });
|
433 | }
|
434 |
|
435 | function restoreCssFromHiddenInit() {
|
436 |
|
437 |
|
438 | $hiddenParents.each(function(i) {
|
439 | var old = oldProps[i];
|
440 | for ( var name in cssShow ) {
|
441 | this.style[ name ] = old[ name ];
|
442 | }
|
443 | });
|
444 | }
|
445 |
|
446 | function registerPlugin(plugin) {
|
447 | plugins.unshift(plugin);
|
448 | plugin.init(self);
|
449 | }
|
450 |
|
451 | function unregisterPlugin(plugin) {
|
452 | for (var i = plugins.length; i >= 0; i--) {
|
453 | if (plugins[i] === plugin) {
|
454 | if (plugins[i].destroy) {
|
455 | plugins[i].destroy();
|
456 | }
|
457 | plugins.splice(i, 1);
|
458 | break;
|
459 | }
|
460 | }
|
461 | }
|
462 |
|
463 | function setSelectionModel(model) {
|
464 | if (selectionModel) {
|
465 | selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged);
|
466 | if (selectionModel.destroy) {
|
467 | selectionModel.destroy();
|
468 | }
|
469 | }
|
470 |
|
471 | selectionModel = model;
|
472 | if (selectionModel) {
|
473 | selectionModel.init(self);
|
474 | selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged);
|
475 | }
|
476 | }
|
477 |
|
478 | function getSelectionModel() {
|
479 | return selectionModel;
|
480 | }
|
481 |
|
482 | function getCanvasNode() {
|
483 | return $canvas[0];
|
484 | }
|
485 |
|
486 | function measureScrollbar() {
|
487 | var $outerdiv = $('<div class="' + $viewport.className + '" style="position:absolute; top:-10000px; left:-10000px; overflow:auto; width:100px; height:100px;"></div>').appendTo($viewport);
|
488 | var $innerdiv = $('<div style="width:200px; height:200px; overflow:auto;"></div>').appendTo($outerdiv);
|
489 | var dim = {
|
490 | width: $outerdiv[0].offsetWidth - $outerdiv[0].clientWidth,
|
491 | height: $outerdiv[0].offsetHeight - $outerdiv[0].clientHeight
|
492 | };
|
493 | $innerdiv.remove();
|
494 | $outerdiv.remove();
|
495 | return dim;
|
496 | }
|
497 |
|
498 | function getColumnTotalWidth(includeScrollbar) {
|
499 | var totalWidth = 0;
|
500 | for (var i = 0, ii = columns.length; i < ii; i++) {
|
501 | var width = columns[i].width;
|
502 | totalWidth += width;
|
503 | }
|
504 | if (includeScrollbar) {
|
505 | totalWidth += scrollbarDimensions.width;
|
506 | }
|
507 | return totalWidth;
|
508 | }
|
509 |
|
510 | function getHeadersWidth() {
|
511 | var headersWidth = getColumnTotalWidth(!options.autoHeight);
|
512 | return Math.max(headersWidth, viewportW) + 1000;
|
513 | }
|
514 |
|
515 | function getCanvasWidth() {
|
516 | var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;
|
517 | var rowWidth = 0;
|
518 | var i = columns.length;
|
519 | while (i--) {
|
520 | rowWidth += columns[i].width;
|
521 | }
|
522 | return options.fullWidthRows ? Math.max(rowWidth, availableWidth) : rowWidth;
|
523 | }
|
524 |
|
525 | function updateCanvasWidth(forceColumnWidthsUpdate) {
|
526 | var oldCanvasWidth = canvasWidth;
|
527 | canvasWidth = getCanvasWidth();
|
528 |
|
529 | if (canvasWidth != oldCanvasWidth) {
|
530 | $canvas.width(canvasWidth);
|
531 | $headerRow.width(canvasWidth);
|
532 | if (options.createFooterRow) { $footerRow.width(canvasWidth); }
|
533 | if (options.createPreHeaderPanel) { $preHeaderPanel.width(canvasWidth); }
|
534 | $headers.width(getHeadersWidth());
|
535 | viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);
|
536 | }
|
537 |
|
538 | var w=canvasWidth + (viewportHasVScroll ? scrollbarDimensions.width : 0);
|
539 | $headerRowSpacer.width(w);
|
540 | if (options.createFooterRow) { $footerRowSpacer.width(w); }
|
541 | if (options.createPreHeaderPanel) { $preHeaderPanelSpacer.width(w); }
|
542 |
|
543 | if (canvasWidth != oldCanvasWidth || forceColumnWidthsUpdate) {
|
544 | applyColumnWidths();
|
545 | }
|
546 | }
|
547 |
|
548 | function disableSelection($target) {
|
549 | if ($target && $target.jquery) {
|
550 | $target
|
551 | .attr("unselectable", "on")
|
552 | .css("MozUserSelect", "none")
|
553 | .on("selectstart.ui", function () {
|
554 | return false;
|
555 | });
|
556 | }
|
557 | }
|
558 |
|
559 | function getMaxSupportedCssHeight() {
|
560 | var supportedHeight = 1000000;
|
561 |
|
562 | var testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;
|
563 | var div = $("<div style='display:none' />").appendTo(document.body);
|
564 |
|
565 | while (true) {
|
566 | var test = supportedHeight * 2;
|
567 | div.css("height", test);
|
568 | if (test > testUpTo || div.height() !== test) {
|
569 | break;
|
570 | } else {
|
571 | supportedHeight = test;
|
572 | }
|
573 | }
|
574 |
|
575 | div.remove();
|
576 | return supportedHeight;
|
577 | }
|
578 |
|
579 | function getUID() {
|
580 | return uid;
|
581 | }
|
582 |
|
583 | function getHeaderColumnWidthDiff() {
|
584 | return headerColumnWidthDiff;
|
585 | }
|
586 |
|
587 | function getScrollbarDimensions() {
|
588 | return scrollbarDimensions;
|
589 | }
|
590 |
|
591 |
|
592 | function bindAncestorScrollEvents() {
|
593 | var elem = $canvas[0];
|
594 | while ((elem = elem.parentNode) != document.body && elem != null) {
|
595 |
|
596 | if (elem == $viewport[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight) {
|
597 | var $elem = $(elem);
|
598 | if (!$boundAncestors) {
|
599 | $boundAncestors = $elem;
|
600 | } else {
|
601 | $boundAncestors = $boundAncestors.add($elem);
|
602 | }
|
603 | $elem.on("scroll." + uid, handleActiveCellPositionChange);
|
604 | }
|
605 | }
|
606 | }
|
607 |
|
608 | function unbindAncestorScrollEvents() {
|
609 | if (!$boundAncestors) {
|
610 | return;
|
611 | }
|
612 | $boundAncestors.off("scroll." + uid);
|
613 | $boundAncestors = null;
|
614 | }
|
615 |
|
616 | function updateColumnHeader(columnId, title, toolTip) {
|
617 | if (!initialized) { return; }
|
618 | var idx = getColumnIndex(columnId);
|
619 | if (idx == null) {
|
620 | return;
|
621 | }
|
622 |
|
623 | var columnDef = columns[idx];
|
624 | var $header = $headers.children().eq(idx);
|
625 | if ($header) {
|
626 | if (title !== undefined) {
|
627 | columns[idx].name = title;
|
628 | }
|
629 | if (toolTip !== undefined) {
|
630 | columns[idx].toolTip = toolTip;
|
631 | }
|
632 |
|
633 | trigger(self.onBeforeHeaderCellDestroy, {
|
634 | "node": $header[0],
|
635 | "column": columnDef,
|
636 | "grid": self
|
637 | });
|
638 |
|
639 | $header
|
640 | .attr("title", toolTip || "")
|
641 | .children().eq(0).html(title);
|
642 |
|
643 | trigger(self.onHeaderCellRendered, {
|
644 | "node": $header[0],
|
645 | "column": columnDef,
|
646 | "grid": self
|
647 | });
|
648 | }
|
649 | }
|
650 |
|
651 | function getHeader() {
|
652 | return $headers[0];
|
653 | }
|
654 |
|
655 | function getHeaderColumn(columnIdOrIdx) {
|
656 | var idx = (typeof columnIdOrIdx === "number" ? columnIdOrIdx : getColumnIndex(columnIdOrIdx));
|
657 | var $rtn = $headers.children().eq(idx);
|
658 | return $rtn && $rtn[0];
|
659 | }
|
660 |
|
661 | function getHeaderRow() {
|
662 | return $headerRow[0];
|
663 | }
|
664 |
|
665 | function getFooterRow() {
|
666 | return $footerRow[0];
|
667 | }
|
668 |
|
669 | function getPreHeaderPanel() {
|
670 | return $preHeaderPanel[0];
|
671 | }
|
672 |
|
673 | function getHeaderRowColumn(columnIdOrIdx) {
|
674 | var idx = (typeof columnIdOrIdx === "number" ? columnIdOrIdx : getColumnIndex(columnIdOrIdx));
|
675 | var $rtn = $headerRow.children().eq(idx);
|
676 | return $rtn && $rtn[0];
|
677 | }
|
678 |
|
679 | function getFooterRowColumn(columnIdOrIdx) {
|
680 | var idx = (typeof columnIdOrIdx === "number" ? columnIdOrIdx : getColumnIndex(columnIdOrIdx));
|
681 | var $rtn = $footerRow.children().eq(idx);
|
682 | return $rtn && $rtn[0];
|
683 | }
|
684 |
|
685 | function createColumnHeaders() {
|
686 | function onMouseEnter() {
|
687 | $(this).addClass("ui-state-hover");
|
688 | }
|
689 |
|
690 | function onMouseLeave() {
|
691 | $(this).removeClass("ui-state-hover");
|
692 | }
|
693 |
|
694 | $headers.find(".slick-header-column")
|
695 | .each(function() {
|
696 | var columnDef = $(this).data("column");
|
697 | if (columnDef) {
|
698 | trigger(self.onBeforeHeaderCellDestroy, {
|
699 | "node": this,
|
700 | "column": columnDef,
|
701 | "grid": self
|
702 | });
|
703 | }
|
704 | });
|
705 | $headers.empty();
|
706 | $headers.width(getHeadersWidth());
|
707 |
|
708 | $headerRow.find(".slick-headerrow-column")
|
709 | .each(function() {
|
710 | var columnDef = $(this).data("column");
|
711 | if (columnDef) {
|
712 | trigger(self.onBeforeHeaderRowCellDestroy, {
|
713 | "node": this,
|
714 | "column": columnDef,
|
715 | "grid": self
|
716 | });
|
717 | }
|
718 | });
|
719 | $headerRow.empty();
|
720 |
|
721 | if (options.createFooterRow) {
|
722 | $footerRow.find(".slick-footerrow-column")
|
723 | .each(function() {
|
724 | var columnDef = $(this).data("column");
|
725 | if (columnDef) {
|
726 | trigger(self.onBeforeFooterRowCellDestroy, {
|
727 | "node": this,
|
728 | "column": columnDef
|
729 | });
|
730 | }
|
731 | });
|
732 | $footerRow.empty();
|
733 | }
|
734 |
|
735 | for (var i = 0; i < columns.length; i++) {
|
736 | var m = columns[i];
|
737 |
|
738 | var header = $("<div class='ui-state-default slick-header-column' />")
|
739 | .html("<span class='slick-column-name'>" + m.name + "</span>")
|
740 | .width(m.width - headerColumnWidthDiff)
|
741 | .attr("id", "" + uid + m.id)
|
742 | .attr("title", m.toolTip || "")
|
743 | .data("column", m)
|
744 | .addClass(m.headerCssClass || "")
|
745 | .appendTo($headers);
|
746 |
|
747 | if (options.enableColumnReorder || m.sortable) {
|
748 | header
|
749 | .on('mouseenter', onMouseEnter)
|
750 | .on('mouseleave', onMouseLeave);
|
751 | }
|
752 |
|
753 | if (m.sortable) {
|
754 | header.addClass("slick-header-sortable");
|
755 | header.append("<span class='slick-sort-indicator"
|
756 | + (options.numberedMultiColumnSort && !options.sortColNumberInSeparateSpan ? " slick-sort-indicator-numbered" : "" ) + "' />");
|
757 | if (options.numberedMultiColumnSort && options.sortColNumberInSeparateSpan) { header.append("<span class='slick-sort-indicator-numbered' />"); }
|
758 | }
|
759 |
|
760 | trigger(self.onHeaderCellRendered, {
|
761 | "node": header[0],
|
762 | "column": m,
|
763 | "grid": self
|
764 | });
|
765 |
|
766 | if (options.showHeaderRow) {
|
767 | var headerRowCell = $("<div class='ui-state-default slick-headerrow-column l" + i + " r" + i + "'></div>")
|
768 | .data("column", m)
|
769 | .appendTo($headerRow);
|
770 |
|
771 | trigger(self.onHeaderRowCellRendered, {
|
772 | "node": headerRowCell[0],
|
773 | "column": m,
|
774 | "grid": self
|
775 | });
|
776 | }
|
777 | if (options.createFooterRow && options.showFooterRow) {
|
778 | var footerRowCell = $("<div class='ui-state-default slick-footerrow-column l" + i + " r" + i + "'></div>")
|
779 | .data("column", m)
|
780 | .appendTo($footerRow);
|
781 |
|
782 | trigger(self.onFooterRowCellRendered, {
|
783 | "node": footerRowCell[0],
|
784 | "column": m
|
785 | });
|
786 | }
|
787 | }
|
788 |
|
789 | setSortColumns(sortColumns);
|
790 | setupColumnResize();
|
791 | if (options.enableColumnReorder) {
|
792 | if (typeof options.enableColumnReorder == 'function') {
|
793 | options.enableColumnReorder(self, $headers, headerColumnWidthDiff, setColumns, setupColumnResize, columns, getColumnIndex, uid, trigger);
|
794 | } else {
|
795 | setupColumnReorder();
|
796 | }
|
797 | }
|
798 | }
|
799 |
|
800 | function setupColumnSort() {
|
801 | $headers.click(function (e) {
|
802 | if (columnResizeDragging) return;
|
803 |
|
804 | e.metaKey = e.metaKey || e.ctrlKey;
|
805 |
|
806 | if ($(e.target).hasClass("slick-resizable-handle")) {
|
807 | return;
|
808 | }
|
809 |
|
810 | var $col = $(e.target).closest(".slick-header-column");
|
811 | if (!$col.length) {
|
812 | return;
|
813 | }
|
814 |
|
815 | var column = $col.data("column");
|
816 | if (column.sortable) {
|
817 | if (!getEditorLock().commitCurrentEdit()) {
|
818 | return;
|
819 | }
|
820 |
|
821 | var sortColumn = null;
|
822 | var i = 0;
|
823 | for (; i < sortColumns.length; i++) {
|
824 | if (sortColumns[i].columnId == column.id) {
|
825 | sortColumn = sortColumns[i];
|
826 | sortColumn.sortAsc = !sortColumn.sortAsc;
|
827 | break;
|
828 | }
|
829 | }
|
830 | var hadSortCol = !!sortColumn;
|
831 |
|
832 | if (options.tristateMultiColumnSort) {
|
833 | if (!sortColumn) {
|
834 | sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc };
|
835 | }
|
836 | if (hadSortCol && sortColumn.sortAsc) {
|
837 |
|
838 | sortColumns.splice(i, 1);
|
839 | sortColumn = null;
|
840 | }
|
841 | if (!options.multiColumnSort) { sortColumns = []; }
|
842 | if (sortColumn && (!hadSortCol || !options.multiColumnSort)) {
|
843 | sortColumns.push(sortColumn);
|
844 | }
|
845 | } else {
|
846 |
|
847 | if (e.metaKey && options.multiColumnSort) {
|
848 | if (sortColumn) {
|
849 | sortColumns.splice(i, 1);
|
850 | }
|
851 | }
|
852 | else {
|
853 | if ((!e.shiftKey && !e.metaKey) || !options.multiColumnSort) {
|
854 | sortColumns = [];
|
855 | }
|
856 |
|
857 | if (!sortColumn) {
|
858 | sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc };
|
859 | sortColumns.push(sortColumn);
|
860 | } else if (sortColumns.length == 0) {
|
861 | sortColumns.push(sortColumn);
|
862 | }
|
863 | }
|
864 | }
|
865 |
|
866 | setSortColumns(sortColumns);
|
867 |
|
868 | if (!options.multiColumnSort) {
|
869 | trigger(self.onSort, {
|
870 | multiColumnSort: false,
|
871 | sortCol: (sortColumns.length > 0 ? column : null),
|
872 | sortAsc: (sortColumns.length > 0 ? sortColumns[0].sortAsc : true)
|
873 | }, e);
|
874 | } else {
|
875 | trigger(self.onSort, {
|
876 | multiColumnSort: true,
|
877 | sortCols: $.map(sortColumns, function(col) {
|
878 | return {sortCol: columns[getColumnIndex(col.columnId)], sortAsc: col.sortAsc };
|
879 | })
|
880 | }, e);
|
881 | }
|
882 | }
|
883 | });
|
884 | }
|
885 |
|
886 | function setupColumnReorder() {
|
887 | $headers.filter(":ui-sortable").sortable("destroy");
|
888 | $headers.sortable({
|
889 | containment: "parent",
|
890 | distance: 3,
|
891 | axis: "x",
|
892 | cursor: "default",
|
893 | tolerance: "intersection",
|
894 | helper: "clone",
|
895 | placeholder: "slick-sortable-placeholder ui-state-default slick-header-column",
|
896 | start: function (e, ui) {
|
897 | ui.placeholder.width(ui.helper.outerWidth() - headerColumnWidthDiff);
|
898 | $(ui.helper).addClass("slick-header-column-active");
|
899 | },
|
900 | beforeStop: function (e, ui) {
|
901 | $(ui.helper).removeClass("slick-header-column-active");
|
902 | },
|
903 | stop: function (e) {
|
904 | if (!getEditorLock().commitCurrentEdit()) {
|
905 | $(this).sortable("cancel");
|
906 | return;
|
907 | }
|
908 |
|
909 | var reorderedIds = $headers.sortable("toArray");
|
910 | var reorderedColumns = [];
|
911 | for (var i = 0; i < reorderedIds.length; i++) {
|
912 | reorderedColumns.push(columns[getColumnIndex(reorderedIds[i].replace(uid, ""))]);
|
913 | }
|
914 | setColumns(reorderedColumns);
|
915 |
|
916 | trigger(self.onColumnsReordered, {});
|
917 | e.stopPropagation();
|
918 | setupColumnResize();
|
919 | }
|
920 | });
|
921 | }
|
922 |
|
923 | function setupColumnResize() {
|
924 | var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;
|
925 | columnElements = $headers.children();
|
926 | columnElements.find(".slick-resizable-handle").remove();
|
927 | columnElements.each(function (i, e) {
|
928 | if (i >= columns.length) { return; }
|
929 | if (columns[i].resizable) {
|
930 | if (firstResizable === undefined) {
|
931 | firstResizable = i;
|
932 | }
|
933 | lastResizable = i;
|
934 | }
|
935 | });
|
936 | if (firstResizable === undefined) {
|
937 | return;
|
938 | }
|
939 | columnElements.each(function (i, e) {
|
940 | if (i >= columns.length) { return; }
|
941 | if (i < firstResizable || (options.forceFitColumns && i >= lastResizable)) {
|
942 | return;
|
943 | }
|
944 | $col = $(e);
|
945 | $("<div class='slick-resizable-handle' />")
|
946 | .appendTo(e)
|
947 | .on("dragstart", function (e, dd) {
|
948 | if (!getEditorLock().commitCurrentEdit()) {
|
949 | return false;
|
950 | }
|
951 | pageX = e.pageX;
|
952 | $(this).parent().addClass("slick-header-column-active");
|
953 | var shrinkLeewayOnRight = null, stretchLeewayOnRight = null;
|
954 |
|
955 | columnElements.each(function (i, e) {
|
956 | if (i >= columns.length) { return; }
|
957 | columns[i].previousWidth = $(e).outerWidth();
|
958 | });
|
959 | if (options.forceFitColumns) {
|
960 | shrinkLeewayOnRight = 0;
|
961 | stretchLeewayOnRight = 0;
|
962 |
|
963 | for (j = i + 1; j < columns.length; j++) {
|
964 | c = columns[j];
|
965 | if (c.resizable) {
|
966 | if (stretchLeewayOnRight !== null) {
|
967 | if (c.maxWidth) {
|
968 | stretchLeewayOnRight += c.maxWidth - c.previousWidth;
|
969 | } else {
|
970 | stretchLeewayOnRight = null;
|
971 | }
|
972 | }
|
973 | shrinkLeewayOnRight += c.previousWidth - Math.max(c.minWidth || 0, absoluteColumnMinWidth);
|
974 | }
|
975 | }
|
976 | }
|
977 | var shrinkLeewayOnLeft = 0, stretchLeewayOnLeft = 0;
|
978 | for (j = 0; j <= i; j++) {
|
979 |
|
980 | c = columns[j];
|
981 | if (c.resizable) {
|
982 | if (stretchLeewayOnLeft !== null) {
|
983 | if (c.maxWidth) {
|
984 | stretchLeewayOnLeft += c.maxWidth - c.previousWidth;
|
985 | } else {
|
986 | stretchLeewayOnLeft = null;
|
987 | }
|
988 | }
|
989 | shrinkLeewayOnLeft += c.previousWidth - Math.max(c.minWidth || 0, absoluteColumnMinWidth);
|
990 | }
|
991 | }
|
992 | if (shrinkLeewayOnRight === null) {
|
993 | shrinkLeewayOnRight = 100000;
|
994 | }
|
995 | if (shrinkLeewayOnLeft === null) {
|
996 | shrinkLeewayOnLeft = 100000;
|
997 | }
|
998 | if (stretchLeewayOnRight === null) {
|
999 | stretchLeewayOnRight = 100000;
|
1000 | }
|
1001 | if (stretchLeewayOnLeft === null) {
|
1002 | stretchLeewayOnLeft = 100000;
|
1003 | }
|
1004 | maxPageX = pageX + Math.min(shrinkLeewayOnRight, stretchLeewayOnLeft);
|
1005 | minPageX = pageX - Math.min(shrinkLeewayOnLeft, stretchLeewayOnRight);
|
1006 | })
|
1007 | .on("drag", function (e, dd) {
|
1008 | columnResizeDragging = true;
|
1009 | var actualMinWidth, d = Math.min(maxPageX, Math.max(minPageX, e.pageX)) - pageX, x;
|
1010 | if (d < 0) {
|
1011 | x = d;
|
1012 | for (j = i; j >= 0; j--) {
|
1013 | c = columns[j];
|
1014 | if (c.resizable) {
|
1015 | actualMinWidth = Math.max(c.minWidth || 0, absoluteColumnMinWidth);
|
1016 | if (x && c.previousWidth + x < actualMinWidth) {
|
1017 | x += c.previousWidth - actualMinWidth;
|
1018 | c.width = actualMinWidth;
|
1019 | } else {
|
1020 | c.width = c.previousWidth + x;
|
1021 | x = 0;
|
1022 | }
|
1023 | }
|
1024 | }
|
1025 |
|
1026 | if (options.forceFitColumns) {
|
1027 | x = -d;
|
1028 | for (j = i + 1; j < columns.length; j++) {
|
1029 | c = columns[j];
|
1030 | if (c.resizable) {
|
1031 | if (x && c.maxWidth && (c.maxWidth - c.previousWidth < x)) {
|
1032 | x -= c.maxWidth - c.previousWidth;
|
1033 | c.width = c.maxWidth;
|
1034 | } else {
|
1035 | c.width = c.previousWidth + x;
|
1036 | x = 0;
|
1037 | }
|
1038 | }
|
1039 | }
|
1040 | }
|
1041 | } else {
|
1042 | x = d;
|
1043 | for (j = i; j >= 0; j--) {
|
1044 | c = columns[j];
|
1045 | if (c.resizable) {
|
1046 | if (x && c.maxWidth && (c.maxWidth - c.previousWidth < x)) {
|
1047 | x -= c.maxWidth - c.previousWidth;
|
1048 | c.width = c.maxWidth;
|
1049 | } else {
|
1050 | c.width = c.previousWidth + x;
|
1051 | x = 0;
|
1052 | }
|
1053 | }
|
1054 | }
|
1055 |
|
1056 | if (options.forceFitColumns) {
|
1057 | x = -d;
|
1058 | for (j = i + 1; j < columns.length; j++) {
|
1059 | c = columns[j];
|
1060 | if (c.resizable) {
|
1061 | actualMinWidth = Math.max(c.minWidth || 0, absoluteColumnMinWidth);
|
1062 | if (x && c.previousWidth + x < actualMinWidth) {
|
1063 | x += c.previousWidth - actualMinWidth;
|
1064 | c.width = actualMinWidth;
|
1065 | } else {
|
1066 | c.width = c.previousWidth + x;
|
1067 | x = 0;
|
1068 | }
|
1069 | }
|
1070 | }
|
1071 | }
|
1072 | }
|
1073 | applyColumnHeaderWidths();
|
1074 | if (options.syncColumnCellResize) {
|
1075 | applyColumnWidths();
|
1076 | }
|
1077 | })
|
1078 | .on("dragend", function (e, dd) {
|
1079 | var newWidth;
|
1080 | $(this).parent().removeClass("slick-header-column-active");
|
1081 | for (j = 0; j < columns.length; j++) {
|
1082 | c = columns[j];
|
1083 | newWidth = $(columnElements[j]).outerWidth();
|
1084 |
|
1085 | if (c.previousWidth !== newWidth && c.rerenderOnResize) {
|
1086 | invalidateAllRows();
|
1087 | }
|
1088 | }
|
1089 | updateCanvasWidth(true);
|
1090 | render();
|
1091 | trigger(self.onColumnsResized, {});
|
1092 | setTimeout(function () { columnResizeDragging = false; }, 300);
|
1093 | });
|
1094 | });
|
1095 | }
|
1096 |
|
1097 | function getVBoxDelta($el) {
|
1098 | var p = ["borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"];
|
1099 | var delta = 0;
|
1100 | $.each(p, function (n, val) {
|
1101 | delta += parseFloat($el.css(val)) || 0;
|
1102 | });
|
1103 | return delta;
|
1104 | }
|
1105 |
|
1106 | function measureCellPaddingAndBorder() {
|
1107 | var el;
|
1108 | var h = ["borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight"];
|
1109 | var v = ["borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"];
|
1110 |
|
1111 |
|
1112 |
|
1113 |
|
1114 | var verArray = $.fn.jquery.split('.');
|
1115 | jQueryNewWidthBehaviour = (verArray[0]==1 && verArray[1]>=8) || verArray[0] >=2;
|
1116 |
|
1117 | el = $("<div class='ui-state-default slick-header-column' style='visibility:hidden'>-</div>").appendTo($headers);
|
1118 | headerColumnWidthDiff = headerColumnHeightDiff = 0;
|
1119 | if (el.css("box-sizing") != "border-box" && el.css("-moz-box-sizing") != "border-box" && el.css("-webkit-box-sizing") != "border-box") {
|
1120 | $.each(h, function (n, val) {
|
1121 | headerColumnWidthDiff += parseFloat(el.css(val)) || 0;
|
1122 | });
|
1123 | $.each(v, function (n, val) {
|
1124 | headerColumnHeightDiff += parseFloat(el.css(val)) || 0;
|
1125 | });
|
1126 | }
|
1127 | el.remove();
|
1128 |
|
1129 | var r = $("<div class='slick-row' />").appendTo($canvas);
|
1130 | el = $("<div class='slick-cell' id='' style='visibility:hidden'>-</div>").appendTo(r);
|
1131 | cellWidthDiff = cellHeightDiff = 0;
|
1132 | if (el.css("box-sizing") != "border-box" && el.css("-moz-box-sizing") != "border-box" && el.css("-webkit-box-sizing") != "border-box") {
|
1133 | $.each(h, function (n, val) {
|
1134 | cellWidthDiff += parseFloat(el.css(val)) || 0;
|
1135 | });
|
1136 | $.each(v, function (n, val) {
|
1137 | cellHeightDiff += parseFloat(el.css(val)) || 0;
|
1138 | });
|
1139 | }
|
1140 | r.remove();
|
1141 |
|
1142 | absoluteColumnMinWidth = Math.max(headerColumnWidthDiff, cellWidthDiff);
|
1143 | }
|
1144 |
|
1145 | function createCssRules() {
|
1146 | $style = $("<style type='text/css' rel='stylesheet' />").appendTo($("head"));
|
1147 | var rowHeight = (options.rowHeight - cellHeightDiff);
|
1148 | var rules = [
|
1149 | "." + uid + " .slick-header-column { left: 1000px; }",
|
1150 | "." + uid + " .slick-top-panel { height:" + options.topPanelHeight + "px; }",
|
1151 | "." + uid + " .slick-preheader-panel { height:" + options.preHeaderPanelHeight + "px; }",
|
1152 | "." + uid + " .slick-headerrow-columns { height:" + options.headerRowHeight + "px; }",
|
1153 | "." + uid + " .slick-footerrow-columns { height:" + options.footerRowHeight + "px; }",
|
1154 | "." + uid + " .slick-cell { height:" + rowHeight + "px; }",
|
1155 | "." + uid + " .slick-row { height:" + options.rowHeight + "px; }"
|
1156 | ];
|
1157 |
|
1158 | for (var i = 0; i < columns.length; i++) {
|
1159 | rules.push("." + uid + " .l" + i + " { }");
|
1160 | rules.push("." + uid + " .r" + i + " { }");
|
1161 | }
|
1162 |
|
1163 | if ($style[0].styleSheet) {
|
1164 | $style[0].styleSheet.cssText = rules.join(" ");
|
1165 | } else {
|
1166 | $style[0].appendChild(document.createTextNode(rules.join(" ")));
|
1167 | }
|
1168 | }
|
1169 |
|
1170 | function getColumnCssRules(idx) {
|
1171 | var i;
|
1172 | if (!stylesheet) {
|
1173 | var sheets = document.styleSheets;
|
1174 | for (i = 0; i < sheets.length; i++) {
|
1175 | if ((sheets[i].ownerNode || sheets[i].owningElement) == $style[0]) {
|
1176 | stylesheet = sheets[i];
|
1177 | break;
|
1178 | }
|
1179 | }
|
1180 |
|
1181 | if (!stylesheet) {
|
1182 | throw new Error("Cannot find stylesheet.");
|
1183 | }
|
1184 |
|
1185 |
|
1186 | columnCssRulesL = [];
|
1187 | columnCssRulesR = [];
|
1188 | var cssRules = (stylesheet.cssRules || stylesheet.rules);
|
1189 | var matches, columnIdx;
|
1190 | for (i = 0; i < cssRules.length; i++) {
|
1191 | var selector = cssRules[i].selectorText;
|
1192 | if (matches = /\.l\d+/.exec(selector)) {
|
1193 | columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);
|
1194 | columnCssRulesL[columnIdx] = cssRules[i];
|
1195 | } else if (matches = /\.r\d+/.exec(selector)) {
|
1196 | columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);
|
1197 | columnCssRulesR[columnIdx] = cssRules[i];
|
1198 | }
|
1199 | }
|
1200 | }
|
1201 |
|
1202 | return {
|
1203 | "left": columnCssRulesL[idx],
|
1204 | "right": columnCssRulesR[idx]
|
1205 | };
|
1206 | }
|
1207 |
|
1208 | function removeCssRules() {
|
1209 | $style.remove();
|
1210 | stylesheet = null;
|
1211 | }
|
1212 |
|
1213 | function destroy() {
|
1214 | getEditorLock().cancelCurrentEdit();
|
1215 |
|
1216 | trigger(self.onBeforeDestroy, {});
|
1217 |
|
1218 | var i = plugins.length;
|
1219 | while(i--) {
|
1220 | unregisterPlugin(plugins[i]);
|
1221 | }
|
1222 |
|
1223 | if (options.enableColumnReorder) {
|
1224 | $headers.filter(":ui-sortable").sortable("destroy");
|
1225 | }
|
1226 |
|
1227 | unbindAncestorScrollEvents();
|
1228 | $container.off(".slickgrid");
|
1229 | removeCssRules();
|
1230 |
|
1231 | $canvas.off("draginit dragstart dragend drag");
|
1232 | $container.empty().removeClass(uid);
|
1233 | }
|
1234 |
|
1235 |
|
1236 |
|
1237 |
|
1238 |
|
1239 | function trigger(evt, args, e) {
|
1240 | e = e || new Slick.EventData();
|
1241 | args = args || {};
|
1242 | args.grid = self;
|
1243 | return evt.notify(args, e, self);
|
1244 | }
|
1245 |
|
1246 | function getEditorLock() {
|
1247 | return options.editorLock;
|
1248 | }
|
1249 |
|
1250 | function getEditController() {
|
1251 | return editController;
|
1252 | }
|
1253 |
|
1254 | function getColumnIndex(id) {
|
1255 | return columnsById[id];
|
1256 | }
|
1257 |
|
1258 | function autosizeColumns() {
|
1259 | var i, c,
|
1260 | widths = [],
|
1261 | shrinkLeeway = 0,
|
1262 | total = 0,
|
1263 | prevTotal,
|
1264 | availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;
|
1265 |
|
1266 | for (i = 0; i < columns.length; i++) {
|
1267 | c = columns[i];
|
1268 | widths.push(c.width);
|
1269 | total += c.width;
|
1270 | if (c.resizable) {
|
1271 | shrinkLeeway += c.width - Math.max(c.minWidth, absoluteColumnMinWidth);
|
1272 | }
|
1273 | }
|
1274 |
|
1275 |
|
1276 | prevTotal = total;
|
1277 | while (total > availWidth && shrinkLeeway) {
|
1278 | var shrinkProportion = (total - availWidth) / shrinkLeeway;
|
1279 | for (i = 0; i < columns.length && total > availWidth; i++) {
|
1280 | c = columns[i];
|
1281 | var width = widths[i];
|
1282 | if (!c.resizable || width <= c.minWidth || width <= absoluteColumnMinWidth) {
|
1283 | continue;
|
1284 | }
|
1285 | var absMinWidth = Math.max(c.minWidth, absoluteColumnMinWidth);
|
1286 | var shrinkSize = Math.floor(shrinkProportion * (width - absMinWidth)) || 1;
|
1287 | shrinkSize = Math.min(shrinkSize, width - absMinWidth);
|
1288 | total -= shrinkSize;
|
1289 | shrinkLeeway -= shrinkSize;
|
1290 | widths[i] -= shrinkSize;
|
1291 | }
|
1292 | if (prevTotal <= total) {
|
1293 | break;
|
1294 | }
|
1295 | prevTotal = total;
|
1296 | }
|
1297 |
|
1298 |
|
1299 | prevTotal = total;
|
1300 | while (total < availWidth) {
|
1301 | var growProportion = availWidth / total;
|
1302 | for (i = 0; i < columns.length && total < availWidth; i++) {
|
1303 | c = columns[i];
|
1304 | var currentWidth = widths[i];
|
1305 | var growSize;
|
1306 |
|
1307 | if (!c.resizable || c.maxWidth <= currentWidth) {
|
1308 | growSize = 0;
|
1309 | } else {
|
1310 | growSize = Math.min(Math.floor(growProportion * currentWidth) - currentWidth, (c.maxWidth - currentWidth) || 1000000) || 1;
|
1311 | }
|
1312 | total += growSize;
|
1313 | widths[i] += (total <= availWidth ? growSize : 0);
|
1314 | }
|
1315 | if (prevTotal >= total) {
|
1316 | break;
|
1317 | }
|
1318 | prevTotal = total;
|
1319 | }
|
1320 |
|
1321 | var reRender = false;
|
1322 | for (i = 0; i < columns.length; i++) {
|
1323 | if (columns[i].rerenderOnResize && columns[i].width != widths[i]) {
|
1324 | reRender = true;
|
1325 | }
|
1326 | columns[i].width = widths[i];
|
1327 | }
|
1328 |
|
1329 | applyColumnHeaderWidths();
|
1330 | updateCanvasWidth(true);
|
1331 |
|
1332 | trigger(self.onAutosizeColumns, { "columns": columns});
|
1333 |
|
1334 | if (reRender) {
|
1335 | invalidateAllRows();
|
1336 | render();
|
1337 | }
|
1338 | }
|
1339 |
|
1340 | function applyColumnHeaderWidths() {
|
1341 | if (!initialized) { return; }
|
1342 | var h;
|
1343 |
|
1344 | for (var i = 0, headers = $headers.children(), ii = columns.length; i < ii; i++) {
|
1345 | h = $(headers[i]);
|
1346 | if (jQueryNewWidthBehaviour) {
|
1347 | if (h.outerWidth() !== columns[i].width) {
|
1348 | h.outerWidth(columns[i].width);
|
1349 | }
|
1350 | } else {
|
1351 | if (h.width() !== columns[i].width - headerColumnWidthDiff) {
|
1352 | h.width(columns[i].width - headerColumnWidthDiff);
|
1353 | }
|
1354 | }
|
1355 | }
|
1356 |
|
1357 | updateColumnCaches();
|
1358 | }
|
1359 |
|
1360 | function applyColumnWidths() {
|
1361 | var x = 0, w, rule;
|
1362 | for (var i = 0; i < columns.length; i++) {
|
1363 | w = columns[i].width;
|
1364 |
|
1365 | rule = getColumnCssRules(i);
|
1366 | rule.left.style.left = x + "px";
|
1367 | rule.right.style.right = (canvasWidth - x - w) + "px";
|
1368 |
|
1369 | x += columns[i].width;
|
1370 | }
|
1371 | }
|
1372 |
|
1373 | function setSortColumn(columnId, ascending) {
|
1374 | setSortColumns([{ columnId: columnId, sortAsc: ascending}]);
|
1375 | }
|
1376 |
|
1377 | function setSortColumns(cols) {
|
1378 | sortColumns = cols;
|
1379 | var numberCols = options.numberedMultiColumnSort && sortColumns.length > 1;
|
1380 | var headerColumnEls = $headers.children();
|
1381 | headerColumnEls
|
1382 | .removeClass("slick-header-column-sorted")
|
1383 | .find(".slick-sort-indicator")
|
1384 | .removeClass("slick-sort-indicator-asc slick-sort-indicator-desc");
|
1385 | headerColumnEls
|
1386 | .find(".slick-sort-indicator-numbered")
|
1387 | .text('');
|
1388 |
|
1389 | $.each(sortColumns, function(i, col) {
|
1390 | if (col.sortAsc == null) {
|
1391 | col.sortAsc = true;
|
1392 | }
|
1393 | var columnIndex = getColumnIndex(col.columnId);
|
1394 | if (columnIndex != null) {
|
1395 | headerColumnEls.eq(columnIndex)
|
1396 | .addClass("slick-header-column-sorted")
|
1397 | .find(".slick-sort-indicator")
|
1398 | .addClass(col.sortAsc ? "slick-sort-indicator-asc" : "slick-sort-indicator-desc");
|
1399 | if (numberCols) {
|
1400 | headerColumnEls.eq(columnIndex)
|
1401 | .find(".slick-sort-indicator-numbered")
|
1402 | .text(i+1);
|
1403 | }
|
1404 | }
|
1405 | });
|
1406 | }
|
1407 |
|
1408 | function getSortColumns() {
|
1409 | return sortColumns;
|
1410 | }
|
1411 |
|
1412 | function handleSelectedRangesChanged(e, ranges) {
|
1413 | selectedRows = [];
|
1414 | var hash = {};
|
1415 | for (var i = 0; i < ranges.length; i++) {
|
1416 | for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
|
1417 | if (!hash[j]) {
|
1418 | selectedRows.push(j);
|
1419 | hash[j] = {};
|
1420 | }
|
1421 | for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) {
|
1422 | if (canCellBeSelected(j, k)) {
|
1423 | hash[j][columns[k].id] = options.selectedCellCssClass;
|
1424 | }
|
1425 | }
|
1426 | }
|
1427 | }
|
1428 |
|
1429 | setCellCssStyles(options.selectedCellCssClass, hash);
|
1430 |
|
1431 | trigger(self.onSelectedRowsChanged, {rows: getSelectedRows()}, e);
|
1432 | }
|
1433 |
|
1434 | function getColumns() {
|
1435 | return columns;
|
1436 | }
|
1437 |
|
1438 | function updateColumnCaches() {
|
1439 |
|
1440 | columnPosLeft = [];
|
1441 | columnPosRight = [];
|
1442 | var x = 0;
|
1443 | for (var i = 0, ii = columns.length; i < ii; i++) {
|
1444 | columnPosLeft[i] = x;
|
1445 | columnPosRight[i] = x + columns[i].width;
|
1446 | x += columns[i].width;
|
1447 | }
|
1448 | }
|
1449 |
|
1450 | function setColumns(columnDefinitions) {
|
1451 | columns = columnDefinitions;
|
1452 |
|
1453 | columnsById = {};
|
1454 | for (var i = 0; i < columns.length; i++) {
|
1455 | var m = columns[i] = $.extend({}, columnDefaults, columns[i]);
|
1456 | columnsById[m.id] = i;
|
1457 | if (m.minWidth && m.width < m.minWidth) {
|
1458 | m.width = m.minWidth;
|
1459 | }
|
1460 | if (m.maxWidth && m.width > m.maxWidth) {
|
1461 | m.width = m.maxWidth;
|
1462 | }
|
1463 | }
|
1464 |
|
1465 | updateColumnCaches();
|
1466 |
|
1467 | if (initialized) {
|
1468 | invalidateAllRows();
|
1469 | createColumnHeaders();
|
1470 | removeCssRules();
|
1471 | createCssRules();
|
1472 | resizeCanvas();
|
1473 | applyColumnWidths();
|
1474 | handleScroll();
|
1475 | }
|
1476 | }
|
1477 |
|
1478 | function getOptions() {
|
1479 | return options;
|
1480 | }
|
1481 |
|
1482 | function setOptions(args, suppressRender) {
|
1483 | if (!getEditorLock().commitCurrentEdit()) {
|
1484 | return;
|
1485 | }
|
1486 |
|
1487 | makeActiveCellNormal();
|
1488 |
|
1489 | if (options.enableAddRow !== args.enableAddRow) {
|
1490 | invalidateRow(getDataLength());
|
1491 | }
|
1492 |
|
1493 | options = $.extend(options, args);
|
1494 | validateAndEnforceOptions();
|
1495 |
|
1496 | $viewport.css("overflow-y", options.autoHeight ? "hidden" : "auto");
|
1497 | if (!suppressRender) { render(); }
|
1498 | }
|
1499 |
|
1500 | function validateAndEnforceOptions() {
|
1501 | if (options.autoHeight) {
|
1502 | options.leaveSpaceForNewRows = false;
|
1503 | }
|
1504 | }
|
1505 |
|
1506 | function setData(newData, scrollToTop) {
|
1507 | data = newData;
|
1508 | invalidateAllRows();
|
1509 | updateRowCount();
|
1510 | if (scrollToTop) {
|
1511 | scrollTo(0);
|
1512 | }
|
1513 | }
|
1514 |
|
1515 | function getData() {
|
1516 | return data;
|
1517 | }
|
1518 |
|
1519 | function getDataLength() {
|
1520 | if (data.getLength) {
|
1521 | return data.getLength();
|
1522 | } else {
|
1523 | return data.length;
|
1524 | }
|
1525 | }
|
1526 |
|
1527 | function getDataLengthIncludingAddNew() {
|
1528 | return getDataLength() + (!options.enableAddRow ? 0
|
1529 | : (!pagingActive || pagingIsLastPage ? 1 : 0)
|
1530 | );
|
1531 | }
|
1532 |
|
1533 | function getDataItem(i) {
|
1534 | if (data.getItem) {
|
1535 | return data.getItem(i);
|
1536 | } else {
|
1537 | return data[i];
|
1538 | }
|
1539 | }
|
1540 |
|
1541 | function getTopPanel() {
|
1542 | return $topPanel[0];
|
1543 | }
|
1544 |
|
1545 | function setTopPanelVisibility(visible) {
|
1546 | if (options.showTopPanel != visible) {
|
1547 | options.showTopPanel = visible;
|
1548 | if (visible) {
|
1549 | $topPanelScroller.slideDown("fast", resizeCanvas);
|
1550 | } else {
|
1551 | $topPanelScroller.slideUp("fast", resizeCanvas);
|
1552 | }
|
1553 | }
|
1554 | }
|
1555 |
|
1556 | function setHeaderRowVisibility(visible) {
|
1557 | if (options.showHeaderRow != visible) {
|
1558 | options.showHeaderRow = visible;
|
1559 | if (visible) {
|
1560 | $headerRowScroller.slideDown("fast", resizeCanvas);
|
1561 | } else {
|
1562 | $headerRowScroller.slideUp("fast", resizeCanvas);
|
1563 | }
|
1564 | }
|
1565 | }
|
1566 |
|
1567 | function setFooterRowVisibility(visible) {
|
1568 | if (options.showFooterRow != visible) {
|
1569 | options.showFooterRow = visible;
|
1570 | if (visible) {
|
1571 | $footerRowScroller.slideDown("fast", resizeCanvas);
|
1572 | } else {
|
1573 | $footerRowScroller.slideUp("fast", resizeCanvas);
|
1574 | }
|
1575 | }
|
1576 | }
|
1577 |
|
1578 | function setPreHeaderPanelVisibility(visible) {
|
1579 | if (options.showPreHeaderPanel != visible) {
|
1580 | options.showPreHeaderPanel = visible;
|
1581 | if (visible) {
|
1582 | $preHeaderPanelScroller.slideDown("fast", resizeCanvas);
|
1583 | } else {
|
1584 | $preHeaderPanelScroller.slideUp("fast", resizeCanvas);
|
1585 | }
|
1586 | }
|
1587 | }
|
1588 |
|
1589 | function getContainerNode() {
|
1590 | return $container.get(0);
|
1591 | }
|
1592 |
|
1593 |
|
1594 |
|
1595 |
|
1596 | function getRowTop(row) {
|
1597 | return options.rowHeight * row - offset;
|
1598 | }
|
1599 |
|
1600 | function getRowFromPosition(y) {
|
1601 | return Math.floor((y + offset) / options.rowHeight);
|
1602 | }
|
1603 |
|
1604 | function scrollTo(y) {
|
1605 | y = Math.max(y, 0);
|
1606 | y = Math.min(y, th - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0));
|
1607 |
|
1608 | var oldOffset = offset;
|
1609 |
|
1610 | page = Math.min(n - 1, Math.floor(y / ph));
|
1611 | offset = Math.round(page * cj);
|
1612 | var newScrollTop = y - offset;
|
1613 |
|
1614 | if (offset != oldOffset) {
|
1615 | var range = getVisibleRange(newScrollTop);
|
1616 | cleanupRows(range);
|
1617 | updateRowPositions();
|
1618 | }
|
1619 |
|
1620 | if (prevScrollTop != newScrollTop) {
|
1621 | vScrollDir = (prevScrollTop + oldOffset < newScrollTop + offset) ? 1 : -1;
|
1622 | $viewport[0].scrollTop = (lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop);
|
1623 |
|
1624 | trigger(self.onViewportChanged, {});
|
1625 | }
|
1626 | }
|
1627 |
|
1628 | function defaultFormatter(row, cell, value, columnDef, dataContext, grid) {
|
1629 | if (value == null) {
|
1630 | return "";
|
1631 | } else {
|
1632 | return (value + "").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
1633 | }
|
1634 | }
|
1635 |
|
1636 | function getFormatter(row, column) {
|
1637 | var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);
|
1638 |
|
1639 |
|
1640 | var columnOverrides = rowMetadata &&
|
1641 | rowMetadata.columns &&
|
1642 | (rowMetadata.columns[column.id] || rowMetadata.columns[getColumnIndex(column.id)]);
|
1643 |
|
1644 | return (columnOverrides && columnOverrides.formatter) ||
|
1645 | (rowMetadata && rowMetadata.formatter) ||
|
1646 | column.formatter ||
|
1647 | (options.formatterFactory && options.formatterFactory.getFormatter(column)) ||
|
1648 | options.defaultFormatter;
|
1649 | }
|
1650 |
|
1651 | function getEditor(row, cell) {
|
1652 | var column = columns[cell];
|
1653 | var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);
|
1654 | var columnMetadata = rowMetadata && rowMetadata.columns;
|
1655 |
|
1656 | if (columnMetadata && columnMetadata[column.id] && columnMetadata[column.id].editor !== undefined) {
|
1657 | return columnMetadata[column.id].editor;
|
1658 | }
|
1659 | if (columnMetadata && columnMetadata[cell] && columnMetadata[cell].editor !== undefined) {
|
1660 | return columnMetadata[cell].editor;
|
1661 | }
|
1662 |
|
1663 | return column.editor || (options.editorFactory && options.editorFactory.getEditor(column));
|
1664 | }
|
1665 |
|
1666 | function getDataItemValueForColumn(item, columnDef) {
|
1667 | if (options.dataItemColumnValueExtractor) {
|
1668 | return options.dataItemColumnValueExtractor(item, columnDef);
|
1669 | }
|
1670 | return item[columnDef.field];
|
1671 | }
|
1672 |
|
1673 | function appendRowHtml(stringArray, row, range, dataLength) {
|
1674 | var d = getDataItem(row);
|
1675 | var dataLoading = row < dataLength && !d;
|
1676 | var rowCss = "slick-row" +
|
1677 | (dataLoading ? " loading" : "") +
|
1678 | (row === activeRow && options.showCellSelection ? " active" : "") +
|
1679 | (row % 2 == 1 ? " odd" : " even");
|
1680 |
|
1681 | if (!d) {
|
1682 | rowCss += " " + options.addNewRowCssClass;
|
1683 | }
|
1684 |
|
1685 | var metadata = data.getItemMetadata && data.getItemMetadata(row);
|
1686 |
|
1687 | if (metadata && metadata.cssClasses) {
|
1688 | rowCss += " " + metadata.cssClasses;
|
1689 | }
|
1690 |
|
1691 | stringArray.push("<div class='ui-widget-content " + rowCss + "' style='top:" + getRowTop(row) + "px'>");
|
1692 |
|
1693 | var colspan, m;
|
1694 | for (var i = 0, ii = columns.length; i < ii; i++) {
|
1695 | m = columns[i];
|
1696 | colspan = 1;
|
1697 | if (metadata && metadata.columns) {
|
1698 | var columnData = metadata.columns[m.id] || metadata.columns[i];
|
1699 | colspan = (columnData && columnData.colspan) || 1;
|
1700 | if (colspan === "*") {
|
1701 | colspan = ii - i;
|
1702 | }
|
1703 | }
|
1704 |
|
1705 |
|
1706 | if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {
|
1707 | if (columnPosLeft[i] > range.rightPx) {
|
1708 |
|
1709 | break;
|
1710 | }
|
1711 |
|
1712 | appendCellHtml(stringArray, row, i, colspan, d);
|
1713 | }
|
1714 |
|
1715 | if (colspan > 1) {
|
1716 | i += (colspan - 1);
|
1717 | }
|
1718 | }
|
1719 |
|
1720 | stringArray.push("</div>");
|
1721 | }
|
1722 |
|
1723 | function appendCellHtml(stringArray, row, cell, colspan, item) {
|
1724 |
|
1725 |
|
1726 |
|
1727 |
|
1728 |
|
1729 | var m = columns[cell];
|
1730 | var cellCss = "slick-cell l" + cell + " r" + Math.min(columns.length - 1, cell + colspan - 1) +
|
1731 | (m.cssClass ? " " + m.cssClass : "");
|
1732 | if (row === activeRow && cell === activeCell && options.showCellSelection) {
|
1733 | cellCss += (" active");
|
1734 | }
|
1735 |
|
1736 |
|
1737 | for (var key in cellCssClasses) {
|
1738 | if (cellCssClasses[key][row] && cellCssClasses[key][row][m.id]) {
|
1739 | cellCss += (" " + cellCssClasses[key][row][m.id]);
|
1740 | }
|
1741 | }
|
1742 |
|
1743 | var value = null, formatterResult = '';
|
1744 | if (item) {
|
1745 | value = getDataItemValueForColumn(item, m);
|
1746 | formatterResult = getFormatter(row, m)(row, cell, value, m, item, self);
|
1747 | if (formatterResult === null || formatterResult === undefined) { formatterResult = ''; }
|
1748 | }
|
1749 |
|
1750 |
|
1751 | var addlCssClasses = trigger(self.onBeforeAppendCell, { row: row, cell: cell, value: value, dataContext: item }) || '';
|
1752 | addlCssClasses += (formatterResult && formatterResult.addClasses ? (addlCssClasses ? ' ' : '') + formatterResult.addClasses : '');
|
1753 |
|
1754 | stringArray.push("<div class='" + cellCss + (addlCssClasses ? ' ' + addlCssClasses : '') + "'>");
|
1755 |
|
1756 |
|
1757 | if (item) {
|
1758 | stringArray.push(Object.prototype.toString.call(formatterResult) !== '[object Object]' ? formatterResult : formatterResult.text);
|
1759 | }
|
1760 |
|
1761 | stringArray.push("</div>");
|
1762 |
|
1763 | rowsCache[row].cellRenderQueue.push(cell);
|
1764 | rowsCache[row].cellColSpans[cell] = colspan;
|
1765 | }
|
1766 |
|
1767 |
|
1768 | function cleanupRows(rangeToKeep) {
|
1769 | for (var i in rowsCache) {
|
1770 | if (((i = parseInt(i, 10)) !== activeRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom)) {
|
1771 | removeRowFromCache(i);
|
1772 | }
|
1773 | }
|
1774 | if (options.enableAsyncPostRenderCleanup) { startPostProcessingCleanup(); }
|
1775 | }
|
1776 |
|
1777 | function invalidate() {
|
1778 | updateRowCount();
|
1779 | invalidateAllRows();
|
1780 | render();
|
1781 | }
|
1782 |
|
1783 | function invalidateAllRows() {
|
1784 | if (currentEditor) {
|
1785 | makeActiveCellNormal();
|
1786 | }
|
1787 | for (var row in rowsCache) {
|
1788 | removeRowFromCache(row);
|
1789 | }
|
1790 | if (options.enableAsyncPostRenderCleanup) { startPostProcessingCleanup(); }
|
1791 | }
|
1792 |
|
1793 | function queuePostProcessedRowForCleanup(cacheEntry, postProcessedRow, rowIdx) {
|
1794 | postProcessgroupId++;
|
1795 |
|
1796 |
|
1797 | for (var columnIdx in postProcessedRow) {
|
1798 | if (postProcessedRow.hasOwnProperty(columnIdx)) {
|
1799 | postProcessedCleanupQueue.push({
|
1800 | actionType: 'C',
|
1801 | groupId: postProcessgroupId,
|
1802 | node: cacheEntry.cellNodesByColumnIdx[ columnIdx | 0],
|
1803 | columnIdx: columnIdx | 0,
|
1804 | rowIdx: rowIdx
|
1805 | });
|
1806 | }
|
1807 | }
|
1808 | postProcessedCleanupQueue.push({
|
1809 | actionType: 'R',
|
1810 | groupId: postProcessgroupId,
|
1811 | node: cacheEntry.rowNode
|
1812 | });
|
1813 | $(cacheEntry.rowNode).detach();
|
1814 | }
|
1815 |
|
1816 | function queuePostProcessedCellForCleanup(cellnode, columnIdx, rowIdx) {
|
1817 | postProcessedCleanupQueue.push({
|
1818 | actionType: 'C',
|
1819 | groupId: postProcessgroupId,
|
1820 | node: cellnode,
|
1821 | columnIdx: columnIdx,
|
1822 | rowIdx: rowIdx
|
1823 | });
|
1824 | $(cellnode).detach();
|
1825 | }
|
1826 |
|
1827 | function removeRowFromCache(row) {
|
1828 | var cacheEntry = rowsCache[row];
|
1829 | if (!cacheEntry) {
|
1830 | return;
|
1831 | }
|
1832 |
|
1833 | if (cacheEntry.rowNode) {
|
1834 | if (rowNodeFromLastMouseWheelEvent === cacheEntry.rowNode) {
|
1835 | cacheEntry.rowNode.style.display = 'none';
|
1836 | zombieRowNodeFromLastMouseWheelEvent = rowNodeFromLastMouseWheelEvent;
|
1837 | zombieRowCacheFromLastMouseWheelEvent = cacheEntry;
|
1838 | zombieRowPostProcessedFromLastMouseWheelEvent = postProcessedRows[row];
|
1839 |
|
1840 | } else {
|
1841 | if (options.enableAsyncPostRenderCleanup && postProcessedRows[row]) {
|
1842 | queuePostProcessedRowForCleanup(cacheEntry, postProcessedRows[row], row);
|
1843 | } else {
|
1844 | $canvas[0].removeChild(cacheEntry.rowNode);
|
1845 | }
|
1846 | }
|
1847 | }
|
1848 |
|
1849 | delete rowsCache[row];
|
1850 | delete postProcessedRows[row];
|
1851 | renderedRows--;
|
1852 | counter_rows_removed++;
|
1853 | }
|
1854 |
|
1855 | function invalidateRows(rows) {
|
1856 | var i, rl;
|
1857 | if (!rows || !rows.length) {
|
1858 | return;
|
1859 | }
|
1860 | vScrollDir = 0;
|
1861 | rl = rows.length;
|
1862 | for (i = 0; i < rl; i++) {
|
1863 | if (currentEditor && activeRow === rows[i]) {
|
1864 | makeActiveCellNormal();
|
1865 | }
|
1866 | if (rowsCache[rows[i]]) {
|
1867 | removeRowFromCache(rows[i]);
|
1868 | }
|
1869 | }
|
1870 | if (options.enableAsyncPostRenderCleanup) { startPostProcessingCleanup(); }
|
1871 | }
|
1872 |
|
1873 | function invalidateRow(row) {
|
1874 | if (!row && row !== 0) { return; }
|
1875 | invalidateRows([row]);
|
1876 | }
|
1877 |
|
1878 | function applyFormatResultToCellNode(formatterResult, cellNode, suppressRemove) {
|
1879 | if (formatterResult === null || formatterResult === undefined) { formatterResult = ''; }
|
1880 | if (Object.prototype.toString.call(formatterResult) !== '[object Object]') {
|
1881 | cellNode.innerHTML = formatterResult;
|
1882 | return;
|
1883 | }
|
1884 | cellNode.innerHTML = formatterResult.text;
|
1885 | if (formatterResult.removeClasses && !suppressRemove) {
|
1886 | $(cellNode).removeClass(formatterResult.removeClasses);
|
1887 | }
|
1888 | if (formatterResult.addClasses) {
|
1889 | $(cellNode).addClass(formatterResult.addClasses);
|
1890 | }
|
1891 | }
|
1892 |
|
1893 | function updateCell(row, cell) {
|
1894 | var cellNode = getCellNode(row, cell);
|
1895 | if (!cellNode) {
|
1896 | return;
|
1897 | }
|
1898 |
|
1899 | var m = columns[cell], d = getDataItem(row);
|
1900 | if (currentEditor && activeRow === row && activeCell === cell) {
|
1901 | currentEditor.loadValue(d);
|
1902 | } else {
|
1903 | var formatterResult = d ? getFormatter(row, m)(row, cell, getDataItemValueForColumn(d, m), m, d, self) : "";
|
1904 | applyFormatResultToCellNode(formatterResult, cellNode);
|
1905 | invalidatePostProcessingResults(row);
|
1906 | }
|
1907 | }
|
1908 |
|
1909 | function updateRow(row) {
|
1910 | var cacheEntry = rowsCache[row];
|
1911 | if (!cacheEntry) {
|
1912 | return;
|
1913 | }
|
1914 |
|
1915 | ensureCellNodesInRowsCache(row);
|
1916 |
|
1917 | var formatterResult, d = getDataItem(row);
|
1918 |
|
1919 | for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {
|
1920 | if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {
|
1921 | continue;
|
1922 | }
|
1923 |
|
1924 | columnIdx = columnIdx | 0;
|
1925 | var m = columns[columnIdx],
|
1926 | node = cacheEntry.cellNodesByColumnIdx[columnIdx];
|
1927 |
|
1928 | if (row === activeRow && columnIdx === activeCell && currentEditor) {
|
1929 | currentEditor.loadValue(d);
|
1930 | } else if (d) {
|
1931 | formatterResult = getFormatter(row, m)(row, columnIdx, getDataItemValueForColumn(d, m), m, d, self);
|
1932 | applyFormatResultToCellNode(formatterResult, node);
|
1933 | } else {
|
1934 | node.innerHTML = "";
|
1935 | }
|
1936 | }
|
1937 |
|
1938 | invalidatePostProcessingResults(row);
|
1939 | }
|
1940 |
|
1941 | function getViewportHeight() {
|
1942 | return parseFloat($.css($container[0], "height", true)) -
|
1943 | parseFloat($.css($container[0], "paddingTop", true)) -
|
1944 | parseFloat($.css($container[0], "paddingBottom", true)) -
|
1945 | parseFloat($.css($headerScroller[0], "height")) - getVBoxDelta($headerScroller) -
|
1946 | (options.showTopPanel ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0) -
|
1947 | (options.showHeaderRow ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0) -
|
1948 | (options.createFooterRow && options.showFooterRow ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0) -
|
1949 | (options.createPreHeaderPanel && options.showPreHeaderPanel ? options.preHeaderPanelHeight + getVBoxDelta($preHeaderPanelScroller) : 0);
|
1950 | }
|
1951 |
|
1952 | function resizeCanvas() {
|
1953 | if (!initialized) { return; }
|
1954 | if (options.autoHeight) {
|
1955 | viewportH = options.rowHeight * getDataLengthIncludingAddNew();
|
1956 | } else {
|
1957 | viewportH = getViewportHeight();
|
1958 | }
|
1959 |
|
1960 | numVisibleRows = Math.ceil(viewportH / options.rowHeight);
|
1961 | viewportW = parseFloat($.css($container[0], "width", true));
|
1962 | if (!options.autoHeight) {
|
1963 | $viewport.height(viewportH);
|
1964 | }
|
1965 |
|
1966 | if (!scrollbarDimensions || !scrollbarDimensions.width) {
|
1967 | scrollbarDimensions = measureScrollbar();
|
1968 | }
|
1969 |
|
1970 | if (options.forceFitColumns) {
|
1971 | autosizeColumns();
|
1972 | }
|
1973 |
|
1974 | updateRowCount();
|
1975 | handleScroll();
|
1976 |
|
1977 | lastRenderedScrollLeft = -1;
|
1978 | render();
|
1979 | }
|
1980 |
|
1981 | function updatePagingStatusFromView( pagingInfo ) {
|
1982 | pagingActive = (pagingInfo.pageSize !== 0);
|
1983 | pagingIsLastPage = (pagingInfo.pageNum == pagingInfo.totalPages - 1);
|
1984 | }
|
1985 |
|
1986 | function updateRowCount() {
|
1987 | if (!initialized) { return; }
|
1988 |
|
1989 | var dataLength = getDataLength();
|
1990 | var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();
|
1991 | var numberOfRows = dataLengthIncludingAddNew +
|
1992 | (options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);
|
1993 |
|
1994 | var oldViewportHasVScroll = viewportHasVScroll;
|
1995 |
|
1996 | viewportHasVScroll = options.alwaysShowVerticalScroll || !options.autoHeight && (numberOfRows * options.rowHeight > viewportH);
|
1997 | viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);
|
1998 |
|
1999 | makeActiveCellNormal();
|
2000 |
|
2001 |
|
2002 |
|
2003 | var r1 = dataLength - 1;
|
2004 | for (var i in rowsCache) {
|
2005 | if (i > r1) {
|
2006 | removeRowFromCache(i);
|
2007 | }
|
2008 | }
|
2009 | if (options.enableAsyncPostRenderCleanup) { startPostProcessingCleanup(); }
|
2010 |
|
2011 | if (activeCellNode && activeRow > r1) {
|
2012 | resetActiveCell();
|
2013 | }
|
2014 |
|
2015 | var oldH = h;
|
2016 | th = Math.max(options.rowHeight * numberOfRows, viewportH - scrollbarDimensions.height);
|
2017 | if (th < maxSupportedCssHeight) {
|
2018 |
|
2019 | h = ph = th;
|
2020 | n = 1;
|
2021 | cj = 0;
|
2022 | } else {
|
2023 |
|
2024 | h = maxSupportedCssHeight;
|
2025 | ph = h / 100;
|
2026 | n = Math.floor(th / ph);
|
2027 | cj = (th - h) / (n - 1);
|
2028 | }
|
2029 |
|
2030 | if (h !== oldH) {
|
2031 | $canvas.css("height", h);
|
2032 | scrollTop = $viewport[0].scrollTop;
|
2033 | }
|
2034 |
|
2035 | var oldScrollTopInRange = (scrollTop + offset <= th - viewportH);
|
2036 |
|
2037 | if (th == 0 || scrollTop == 0) {
|
2038 | page = offset = 0;
|
2039 | } else if (oldScrollTopInRange) {
|
2040 |
|
2041 | scrollTo(scrollTop + offset);
|
2042 | } else {
|
2043 |
|
2044 | scrollTo(th - viewportH);
|
2045 | }
|
2046 |
|
2047 | if (h != oldH && options.autoHeight) {
|
2048 | resizeCanvas();
|
2049 | }
|
2050 |
|
2051 | if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {
|
2052 | autosizeColumns();
|
2053 | }
|
2054 | updateCanvasWidth(false);
|
2055 | }
|
2056 |
|
2057 | function getVisibleRange(viewportTop, viewportLeft) {
|
2058 | if (viewportTop == null) {
|
2059 | viewportTop = scrollTop;
|
2060 | }
|
2061 | if (viewportLeft == null) {
|
2062 | viewportLeft = scrollLeft;
|
2063 | }
|
2064 |
|
2065 | return {
|
2066 | top: getRowFromPosition(viewportTop),
|
2067 | bottom: getRowFromPosition(viewportTop + viewportH) + 1,
|
2068 | leftPx: viewportLeft,
|
2069 | rightPx: viewportLeft + viewportW
|
2070 | };
|
2071 | }
|
2072 |
|
2073 | function getRenderedRange(viewportTop, viewportLeft) {
|
2074 | var range = getVisibleRange(viewportTop, viewportLeft);
|
2075 | var buffer = Math.round(viewportH / options.rowHeight);
|
2076 | var minBuffer = options.minRowBuffer;
|
2077 |
|
2078 | if (vScrollDir == -1) {
|
2079 | range.top -= buffer;
|
2080 | range.bottom += minBuffer;
|
2081 | } else if (vScrollDir == 1) {
|
2082 | range.top -= minBuffer;
|
2083 | range.bottom += buffer;
|
2084 | } else {
|
2085 | range.top -= minBuffer;
|
2086 | range.bottom += minBuffer;
|
2087 | }
|
2088 |
|
2089 | range.top = Math.max(0, range.top);
|
2090 | range.bottom = Math.min(getDataLengthIncludingAddNew() - 1, range.bottom);
|
2091 |
|
2092 | range.leftPx -= viewportW;
|
2093 | range.rightPx += viewportW;
|
2094 |
|
2095 | range.leftPx = Math.max(0, range.leftPx);
|
2096 | range.rightPx = Math.min(canvasWidth, range.rightPx);
|
2097 |
|
2098 | return range;
|
2099 | }
|
2100 |
|
2101 | function ensureCellNodesInRowsCache(row) {
|
2102 | var cacheEntry = rowsCache[row];
|
2103 | if (cacheEntry) {
|
2104 | if (cacheEntry.cellRenderQueue.length) {
|
2105 | var lastChild = cacheEntry.rowNode.lastChild;
|
2106 | while (cacheEntry.cellRenderQueue.length) {
|
2107 | var columnIdx = cacheEntry.cellRenderQueue.pop();
|
2108 | cacheEntry.cellNodesByColumnIdx[columnIdx] = lastChild;
|
2109 | lastChild = lastChild.previousSibling;
|
2110 | }
|
2111 | }
|
2112 | }
|
2113 | }
|
2114 |
|
2115 | function cleanUpCells(range, row) {
|
2116 | var totalCellsRemoved = 0;
|
2117 | var cacheEntry = rowsCache[row];
|
2118 |
|
2119 |
|
2120 | var cellsToRemove = [];
|
2121 | for (var i in cacheEntry.cellNodesByColumnIdx) {
|
2122 |
|
2123 | if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(i)) {
|
2124 | continue;
|
2125 | }
|
2126 |
|
2127 |
|
2128 | i = i | 0;
|
2129 |
|
2130 | var colspan = cacheEntry.cellColSpans[i];
|
2131 | if (columnPosLeft[i] > range.rightPx ||
|
2132 | columnPosRight[Math.min(columns.length - 1, i + colspan - 1)] < range.leftPx) {
|
2133 | if (!(row == activeRow && i == activeCell)) {
|
2134 | cellsToRemove.push(i);
|
2135 | }
|
2136 | }
|
2137 | }
|
2138 |
|
2139 | var cellToRemove, node;
|
2140 | postProcessgroupId++;
|
2141 | while ((cellToRemove = cellsToRemove.pop()) != null) {
|
2142 | node = cacheEntry.cellNodesByColumnIdx[cellToRemove];
|
2143 | if (options.enableAsyncPostRenderCleanup && postProcessedRows[row] && postProcessedRows[row][cellToRemove]) {
|
2144 | queuePostProcessedCellForCleanup(node, cellToRemove, row);
|
2145 | } else {
|
2146 | cacheEntry.rowNode.removeChild(node);
|
2147 | }
|
2148 |
|
2149 | delete cacheEntry.cellColSpans[cellToRemove];
|
2150 | delete cacheEntry.cellNodesByColumnIdx[cellToRemove];
|
2151 | if (postProcessedRows[row]) {
|
2152 | delete postProcessedRows[row][cellToRemove];
|
2153 | }
|
2154 | totalCellsRemoved++;
|
2155 | }
|
2156 | }
|
2157 |
|
2158 | function cleanUpAndRenderCells(range) {
|
2159 | var cacheEntry;
|
2160 | var stringArray = [];
|
2161 | var processedRows = [];
|
2162 | var cellsAdded;
|
2163 | var totalCellsAdded = 0;
|
2164 | var colspan;
|
2165 |
|
2166 | for (var row = range.top, btm = range.bottom; row <= btm; row++) {
|
2167 | cacheEntry = rowsCache[row];
|
2168 | if (!cacheEntry) {
|
2169 | continue;
|
2170 | }
|
2171 |
|
2172 |
|
2173 | ensureCellNodesInRowsCache(row);
|
2174 |
|
2175 | cleanUpCells(range, row);
|
2176 |
|
2177 |
|
2178 | cellsAdded = 0;
|
2179 |
|
2180 | var metadata = data.getItemMetadata && data.getItemMetadata(row);
|
2181 | metadata = metadata && metadata.columns;
|
2182 |
|
2183 | var d = getDataItem(row);
|
2184 |
|
2185 |
|
2186 | for (var i = 0, ii = columns.length; i < ii; i++) {
|
2187 |
|
2188 | if (columnPosLeft[i] > range.rightPx) {
|
2189 | break;
|
2190 | }
|
2191 |
|
2192 |
|
2193 | if ((colspan = cacheEntry.cellColSpans[i]) != null) {
|
2194 | i += (colspan > 1 ? colspan - 1 : 0);
|
2195 | continue;
|
2196 | }
|
2197 |
|
2198 | colspan = 1;
|
2199 | if (metadata) {
|
2200 | var columnData = metadata[columns[i].id] || metadata[i];
|
2201 | colspan = (columnData && columnData.colspan) || 1;
|
2202 | if (colspan === "*") {
|
2203 | colspan = ii - i;
|
2204 | }
|
2205 | }
|
2206 |
|
2207 | if (columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) {
|
2208 | appendCellHtml(stringArray, row, i, colspan, d);
|
2209 | cellsAdded++;
|
2210 | }
|
2211 |
|
2212 | i += (colspan > 1 ? colspan - 1 : 0);
|
2213 | }
|
2214 |
|
2215 | if (cellsAdded) {
|
2216 | totalCellsAdded += cellsAdded;
|
2217 | processedRows.push(row);
|
2218 | }
|
2219 | }
|
2220 |
|
2221 | if (!stringArray.length) {
|
2222 | return;
|
2223 | }
|
2224 |
|
2225 | var x = document.createElement("div");
|
2226 | x.innerHTML = stringArray.join("");
|
2227 |
|
2228 | var processedRow;
|
2229 | var node;
|
2230 | while ((processedRow = processedRows.pop()) != null) {
|
2231 | cacheEntry = rowsCache[processedRow];
|
2232 | var columnIdx;
|
2233 | while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null) {
|
2234 | node = x.lastChild;
|
2235 | cacheEntry.rowNode.appendChild(node);
|
2236 | cacheEntry.cellNodesByColumnIdx[columnIdx] = node;
|
2237 | }
|
2238 | }
|
2239 | }
|
2240 |
|
2241 | function renderRows(range) {
|
2242 | var parentNode = $canvas[0],
|
2243 | stringArray = [],
|
2244 | rows = [],
|
2245 | needToReselectCell = false,
|
2246 | dataLength = getDataLength();
|
2247 |
|
2248 | for (var i = range.top, ii = range.bottom; i <= ii; i++) {
|
2249 | if (rowsCache[i]) {
|
2250 | continue;
|
2251 | }
|
2252 | renderedRows++;
|
2253 | rows.push(i);
|
2254 |
|
2255 |
|
2256 |
|
2257 | rowsCache[i] = {
|
2258 | "rowNode": null,
|
2259 |
|
2260 |
|
2261 |
|
2262 | "cellColSpans": [],
|
2263 |
|
2264 |
|
2265 | "cellNodesByColumnIdx": [],
|
2266 |
|
2267 |
|
2268 |
|
2269 |
|
2270 | "cellRenderQueue": []
|
2271 | };
|
2272 |
|
2273 | appendRowHtml(stringArray, i, range, dataLength);
|
2274 | if (activeCellNode && activeRow === i) {
|
2275 | needToReselectCell = true;
|
2276 | }
|
2277 | counter_rows_rendered++;
|
2278 | }
|
2279 |
|
2280 | if (!rows.length) { return; }
|
2281 |
|
2282 | var x = document.createElement("div");
|
2283 | x.innerHTML = stringArray.join("");
|
2284 |
|
2285 | for (var i = 0, ii = rows.length; i < ii; i++) {
|
2286 | rowsCache[rows[i]].rowNode = parentNode.appendChild(x.firstChild);
|
2287 | }
|
2288 |
|
2289 | if (needToReselectCell) {
|
2290 | activeCellNode = getCellNode(activeRow, activeCell);
|
2291 | }
|
2292 | }
|
2293 |
|
2294 | function startPostProcessing() {
|
2295 | if (!options.enableAsyncPostRender) {
|
2296 | return;
|
2297 | }
|
2298 | clearTimeout(h_postrender);
|
2299 | h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);
|
2300 | }
|
2301 |
|
2302 | function startPostProcessingCleanup() {
|
2303 | if (!options.enableAsyncPostRenderCleanup) {
|
2304 | return;
|
2305 | }
|
2306 | clearTimeout(h_postrenderCleanup);
|
2307 | h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);
|
2308 | }
|
2309 |
|
2310 | function invalidatePostProcessingResults(row) {
|
2311 |
|
2312 | for (var columnIdx in postProcessedRows[row]) {
|
2313 | if (postProcessedRows[row].hasOwnProperty(columnIdx)) {
|
2314 | postProcessedRows[row][columnIdx] = 'C';
|
2315 | }
|
2316 | }
|
2317 | postProcessFromRow = Math.min(postProcessFromRow, row);
|
2318 | postProcessToRow = Math.max(postProcessToRow, row);
|
2319 | startPostProcessing();
|
2320 | }
|
2321 |
|
2322 | function updateRowPositions() {
|
2323 | for (var row in rowsCache) {
|
2324 | rowsCache[row].rowNode.style.top = getRowTop(row) + "px";
|
2325 | }
|
2326 | }
|
2327 |
|
2328 | function render() {
|
2329 | if (!initialized) { return; }
|
2330 |
|
2331 | scrollThrottle.dequeue();
|
2332 |
|
2333 | var visible = getVisibleRange();
|
2334 | var rendered = getRenderedRange();
|
2335 |
|
2336 |
|
2337 | cleanupRows(rendered);
|
2338 |
|
2339 |
|
2340 | if (lastRenderedScrollLeft != scrollLeft) {
|
2341 | cleanUpAndRenderCells(rendered);
|
2342 | }
|
2343 |
|
2344 |
|
2345 | renderRows(rendered);
|
2346 |
|
2347 | postProcessFromRow = visible.top;
|
2348 | postProcessToRow = Math.min(getDataLengthIncludingAddNew() - 1, visible.bottom);
|
2349 | startPostProcessing();
|
2350 |
|
2351 | lastRenderedScrollTop = scrollTop;
|
2352 | lastRenderedScrollLeft = scrollLeft;
|
2353 | h_render = null;
|
2354 | }
|
2355 |
|
2356 | function handleHeaderScroll() {
|
2357 | handleElementScroll($headerScroller[0]);
|
2358 | }
|
2359 |
|
2360 | function handleHeaderRowScroll() {
|
2361 | handleElementScroll($headerRowScroller[0]);
|
2362 | }
|
2363 |
|
2364 | function handleFooterRowScroll() {
|
2365 | handleElementScroll($footerRowScroller[0]);
|
2366 | }
|
2367 |
|
2368 | function handlePreHeaderPanelScroll() {
|
2369 | handleElementScroll($preHeaderPanelScroller[0]);
|
2370 | }
|
2371 |
|
2372 | function handleElementScroll(element) {
|
2373 | var scrollLeft = element.scrollLeft;
|
2374 | if (scrollLeft != $viewport[0].scrollLeft) {
|
2375 | $viewport[0].scrollLeft = scrollLeft;
|
2376 | }
|
2377 | }
|
2378 |
|
2379 | function handleScroll() {
|
2380 | scrollTop = $viewport[0].scrollTop;
|
2381 | scrollLeft = $viewport[0].scrollLeft;
|
2382 | var vScrollDist = Math.abs(scrollTop - prevScrollTop);
|
2383 | var hScrollDist = Math.abs(scrollLeft - prevScrollLeft);
|
2384 |
|
2385 | if (hScrollDist) {
|
2386 | prevScrollLeft = scrollLeft;
|
2387 | $headerScroller[0].scrollLeft = scrollLeft;
|
2388 | $topPanelScroller[0].scrollLeft = scrollLeft;
|
2389 | $headerRowScroller[0].scrollLeft = scrollLeft;
|
2390 | if (options.createFooterRow) {
|
2391 | $footerRowScroller[0].scrollLeft = scrollLeft;
|
2392 | }
|
2393 | if (options.createPreHeaderPanel) {
|
2394 | $preHeaderPanelScroller[0].scrollLeft = scrollLeft;
|
2395 | }
|
2396 | }
|
2397 |
|
2398 | if (vScrollDist) {
|
2399 | vScrollDir = prevScrollTop < scrollTop ? 1 : -1;
|
2400 | prevScrollTop = scrollTop;
|
2401 |
|
2402 |
|
2403 | if (vScrollDist < viewportH) {
|
2404 | scrollTo(scrollTop + offset);
|
2405 | } else {
|
2406 | var oldOffset = offset;
|
2407 | if (h == viewportH) {
|
2408 | page = 0;
|
2409 | } else {
|
2410 | page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph)));
|
2411 | }
|
2412 | offset = Math.round(page * cj);
|
2413 | if (oldOffset != offset) {
|
2414 | invalidateAllRows();
|
2415 | }
|
2416 | }
|
2417 | }
|
2418 |
|
2419 | if (hScrollDist || vScrollDist) {
|
2420 | var dx = Math.abs(lastRenderedScrollLeft - scrollLeft);
|
2421 | var dy = Math.abs(lastRenderedScrollTop - scrollTop);
|
2422 | if (dx > 20 || dy > 20) {
|
2423 |
|
2424 | if (options.forceSyncScrolling || (dy < viewportH && dx < viewportW)) {
|
2425 | render();
|
2426 | } else {
|
2427 |
|
2428 | scrollThrottle.enqueue();
|
2429 | }
|
2430 |
|
2431 | trigger(self.onViewportChanged, {});
|
2432 | }
|
2433 | }
|
2434 |
|
2435 | trigger(self.onScroll, {scrollLeft: scrollLeft, scrollTop: scrollTop});
|
2436 | }
|
2437 |
|
2438 | |
2439 |
|
2440 |
|
2441 |
|
2442 |
|
2443 | function ActionThrottle(action, minPeriod_ms) {
|
2444 |
|
2445 | var blocked = false;
|
2446 | var queued = false;
|
2447 |
|
2448 | function enqueue() {
|
2449 | if (!blocked) {
|
2450 | blockAndExecute();
|
2451 | } else {
|
2452 | queued = true;
|
2453 | }
|
2454 | }
|
2455 |
|
2456 | function dequeue() {
|
2457 | queued = false;
|
2458 | }
|
2459 |
|
2460 | function blockAndExecute() {
|
2461 | blocked = true;
|
2462 | setTimeout(unblock, minPeriod_ms);
|
2463 | action();
|
2464 | }
|
2465 |
|
2466 | function unblock() {
|
2467 | if (queued) {
|
2468 | dequeue();
|
2469 | blockAndExecute();
|
2470 | } else {
|
2471 | blocked = false;
|
2472 | }
|
2473 | }
|
2474 |
|
2475 | return {
|
2476 | enqueue: enqueue,
|
2477 | dequeue: dequeue
|
2478 | }
|
2479 | }
|
2480 |
|
2481 | function asyncPostProcessRows() {
|
2482 | var dataLength = getDataLength();
|
2483 | while (postProcessFromRow <= postProcessToRow) {
|
2484 | var row = (vScrollDir >= 0) ? postProcessFromRow++ : postProcessToRow--;
|
2485 | var cacheEntry = rowsCache[row];
|
2486 | if (!cacheEntry || row >= dataLength) {
|
2487 | continue;
|
2488 | }
|
2489 |
|
2490 | if (!postProcessedRows[row]) {
|
2491 | postProcessedRows[row] = {};
|
2492 | }
|
2493 |
|
2494 | ensureCellNodesInRowsCache(row);
|
2495 | for (var columnIdx in cacheEntry.cellNodesByColumnIdx) {
|
2496 | if (!cacheEntry.cellNodesByColumnIdx.hasOwnProperty(columnIdx)) {
|
2497 | continue;
|
2498 | }
|
2499 |
|
2500 | columnIdx = columnIdx | 0;
|
2501 |
|
2502 | var m = columns[columnIdx];
|
2503 | var processedStatus = postProcessedRows[row][columnIdx];
|
2504 | if (m.asyncPostRender && processedStatus !== 'R') {
|
2505 | var node = cacheEntry.cellNodesByColumnIdx[columnIdx];
|
2506 | if (node) {
|
2507 | m.asyncPostRender(node, row, getDataItem(row), m, (processedStatus === 'C'));
|
2508 | }
|
2509 | postProcessedRows[row][columnIdx] = 'R';
|
2510 | }
|
2511 | }
|
2512 |
|
2513 | h_postrender = setTimeout(asyncPostProcessRows, options.asyncPostRenderDelay);
|
2514 | return;
|
2515 | }
|
2516 | }
|
2517 |
|
2518 | function asyncPostProcessCleanupRows() {
|
2519 | if (postProcessedCleanupQueue.length > 0) {
|
2520 | var groupId = postProcessedCleanupQueue[0].groupId;
|
2521 |
|
2522 |
|
2523 | while (postProcessedCleanupQueue.length > 0 && postProcessedCleanupQueue[0].groupId == groupId) {
|
2524 | var entry = postProcessedCleanupQueue.shift();
|
2525 | if (entry.actionType == 'R') {
|
2526 | $(entry.node).remove();
|
2527 | }
|
2528 | if (entry.actionType == 'C') {
|
2529 | var column = columns[entry.columnIdx];
|
2530 | if (column.asyncPostRenderCleanup && entry.node) {
|
2531 |
|
2532 | column.asyncPostRenderCleanup(entry.node, entry.rowIdx, column);
|
2533 | }
|
2534 | }
|
2535 | }
|
2536 |
|
2537 |
|
2538 | h_postrenderCleanup = setTimeout(asyncPostProcessCleanupRows, options.asyncPostRenderCleanupDelay);
|
2539 | }
|
2540 | }
|
2541 |
|
2542 | function updateCellCssStylesOnRenderedRows(addedHash, removedHash) {
|
2543 | var node, columnId, addedRowHash, removedRowHash;
|
2544 | for (var row in rowsCache) {
|
2545 | removedRowHash = removedHash && removedHash[row];
|
2546 | addedRowHash = addedHash && addedHash[row];
|
2547 |
|
2548 | if (removedRowHash) {
|
2549 | for (columnId in removedRowHash) {
|
2550 | if (!addedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {
|
2551 | node = getCellNode(row, getColumnIndex(columnId));
|
2552 | if (node) {
|
2553 | $(node).removeClass(removedRowHash[columnId]);
|
2554 | }
|
2555 | }
|
2556 | }
|
2557 | }
|
2558 |
|
2559 | if (addedRowHash) {
|
2560 | for (columnId in addedRowHash) {
|
2561 | if (!removedRowHash || removedRowHash[columnId] != addedRowHash[columnId]) {
|
2562 | node = getCellNode(row, getColumnIndex(columnId));
|
2563 | if (node) {
|
2564 | $(node).addClass(addedRowHash[columnId]);
|
2565 | }
|
2566 | }
|
2567 | }
|
2568 | }
|
2569 | }
|
2570 | }
|
2571 |
|
2572 | function addCellCssStyles(key, hash) {
|
2573 | if (cellCssClasses[key]) {
|
2574 | throw new Error("addCellCssStyles: cell CSS hash with key '" + key + "' already exists.");
|
2575 | }
|
2576 |
|
2577 | cellCssClasses[key] = hash;
|
2578 | updateCellCssStylesOnRenderedRows(hash, null);
|
2579 |
|
2580 | trigger(self.onCellCssStylesChanged, { "key": key, "hash": hash, "grid": self });
|
2581 | }
|
2582 |
|
2583 | function removeCellCssStyles(key) {
|
2584 | if (!cellCssClasses[key]) {
|
2585 | return;
|
2586 | }
|
2587 |
|
2588 | updateCellCssStylesOnRenderedRows(null, cellCssClasses[key]);
|
2589 | delete cellCssClasses[key];
|
2590 |
|
2591 | trigger(self.onCellCssStylesChanged, { "key": key, "hash": null, "grid": self });
|
2592 | }
|
2593 |
|
2594 | function setCellCssStyles(key, hash) {
|
2595 | var prevHash = cellCssClasses[key];
|
2596 |
|
2597 | cellCssClasses[key] = hash;
|
2598 | updateCellCssStylesOnRenderedRows(hash, prevHash);
|
2599 |
|
2600 | trigger(self.onCellCssStylesChanged, { "key": key, "hash": hash, "grid": self });
|
2601 | }
|
2602 |
|
2603 | function getCellCssStyles(key) {
|
2604 | return cellCssClasses[key];
|
2605 | }
|
2606 |
|
2607 | function flashCell(row, cell, speed) {
|
2608 | speed = speed || 100;
|
2609 | if (rowsCache[row]) {
|
2610 | var $cell = $(getCellNode(row, cell));
|
2611 |
|
2612 | function toggleCellClass(times) {
|
2613 | if (!times) {
|
2614 | return;
|
2615 | }
|
2616 | setTimeout(function () {
|
2617 | $cell.queue(function () {
|
2618 | $cell.toggleClass(options.cellFlashingCssClass).dequeue();
|
2619 | toggleCellClass(times - 1);
|
2620 | });
|
2621 | },
|
2622 | speed);
|
2623 | }
|
2624 |
|
2625 | toggleCellClass(4);
|
2626 | }
|
2627 | }
|
2628 |
|
2629 |
|
2630 |
|
2631 |
|
2632 | function handleMouseWheel(e) {
|
2633 | var rowNode = $(e.target).closest(".slick-row")[0];
|
2634 | if (rowNode != rowNodeFromLastMouseWheelEvent) {
|
2635 | if (zombieRowNodeFromLastMouseWheelEvent && zombieRowNodeFromLastMouseWheelEvent != rowNode) {
|
2636 | if (options.enableAsyncPostRenderCleanup && zombieRowPostProcessedFromLastMouseWheelEvent) {
|
2637 | queuePostProcessedRowForCleanup(zombieRowCacheFromLastMouseWheelEvent,
|
2638 | zombieRowPostProcessedFromLastMouseWheelEvent);
|
2639 | } else {
|
2640 | $canvas[0].removeChild(zombieRowNodeFromLastMouseWheelEvent);
|
2641 | }
|
2642 | zombieRowNodeFromLastMouseWheelEvent = null;
|
2643 | zombieRowCacheFromLastMouseWheelEvent = null;
|
2644 | zombieRowPostProcessedFromLastMouseWheelEvent = null;
|
2645 |
|
2646 | if (options.enableAsyncPostRenderCleanup) { startPostProcessingCleanup(); }
|
2647 | }
|
2648 | rowNodeFromLastMouseWheelEvent = rowNode;
|
2649 | }
|
2650 | }
|
2651 |
|
2652 | function handleDragInit(e, dd) {
|
2653 | var cell = getCellFromEvent(e);
|
2654 | if (!cell || !cellExists(cell.row, cell.cell)) {
|
2655 | return false;
|
2656 | }
|
2657 |
|
2658 | var retval = trigger(self.onDragInit, dd, e);
|
2659 | if (e.isImmediatePropagationStopped()) {
|
2660 | return retval;
|
2661 | }
|
2662 |
|
2663 |
|
2664 |
|
2665 | return false;
|
2666 | }
|
2667 |
|
2668 | function handleDragStart(e, dd) {
|
2669 | var cell = getCellFromEvent(e);
|
2670 | if (!cell || !cellExists(cell.row, cell.cell)) {
|
2671 | return false;
|
2672 | }
|
2673 |
|
2674 | var retval = trigger(self.onDragStart, dd, e);
|
2675 | if (e.isImmediatePropagationStopped()) {
|
2676 | return retval;
|
2677 | }
|
2678 |
|
2679 | return false;
|
2680 | }
|
2681 |
|
2682 | function handleDrag(e, dd) {
|
2683 | return trigger(self.onDrag, dd, e);
|
2684 | }
|
2685 |
|
2686 | function handleDragEnd(e, dd) {
|
2687 | trigger(self.onDragEnd, dd, e);
|
2688 | }
|
2689 |
|
2690 | function handleKeyDown(e) {
|
2691 | trigger(self.onKeyDown, {row: activeRow, cell: activeCell}, e);
|
2692 | var handled = e.isImmediatePropagationStopped();
|
2693 | var keyCode = Slick.keyCode;
|
2694 |
|
2695 | if (!handled) {
|
2696 | if (!e.shiftKey && !e.altKey) {
|
2697 | if (options.editable && currentEditor && currentEditor.keyCaptureList) {
|
2698 | if (currentEditor.keyCaptureList.indexOf(e.which) > -1) {
|
2699 | return;
|
2700 | }
|
2701 | }
|
2702 | if (e.which == keyCode.HOME) {
|
2703 | handled = (e.ctrlKey) ? navigateTop() : navigateRowStart();
|
2704 | } else if (e.which == keyCode.END) {
|
2705 | handled = (e.ctrlKey) ? navigateBottom() : navigateRowEnd();
|
2706 | }
|
2707 | }
|
2708 | }
|
2709 | if (!handled) {
|
2710 | if (!e.shiftKey && !e.altKey && !e.ctrlKey) {
|
2711 |
|
2712 | if (options.editable && currentEditor && currentEditor.keyCaptureList) {
|
2713 | if (currentEditor.keyCaptureList.indexOf( e.which ) > -1) {
|
2714 | return;
|
2715 | }
|
2716 | }
|
2717 | if (e.which == keyCode.ESCAPE) {
|
2718 | if (!getEditorLock().isActive()) {
|
2719 | return;
|
2720 | }
|
2721 | cancelEditAndSetFocus();
|
2722 | } else if (e.which == keyCode.PAGE_DOWN) {
|
2723 | navigatePageDown();
|
2724 | handled = true;
|
2725 | } else if (e.which == keyCode.PAGE_UP) {
|
2726 | navigatePageUp();
|
2727 | handled = true;
|
2728 | } else if (e.which == keyCode.LEFT) {
|
2729 | handled = navigateLeft();
|
2730 | } else if (e.which == keyCode.RIGHT) {
|
2731 | handled = navigateRight();
|
2732 | } else if (e.which == keyCode.UP) {
|
2733 | handled = navigateUp();
|
2734 | } else if (e.which == keyCode.DOWN) {
|
2735 | handled = navigateDown();
|
2736 | } else if (e.which == keyCode.TAB) {
|
2737 | handled = navigateNext();
|
2738 | } else if (e.which == keyCode.ENTER) {
|
2739 | if (options.editable) {
|
2740 | if (currentEditor) {
|
2741 |
|
2742 | if (activeRow === getDataLength()) {
|
2743 | navigateDown();
|
2744 | } else {
|
2745 | commitEditAndSetFocus();
|
2746 | }
|
2747 | } else {
|
2748 | if (getEditorLock().commitCurrentEdit()) {
|
2749 | makeActiveCellEditable();
|
2750 | }
|
2751 | }
|
2752 | }
|
2753 | handled = true;
|
2754 | }
|
2755 | } else if (e.which == keyCode.TAB && e.shiftKey && !e.ctrlKey && !e.altKey) {
|
2756 | handled = navigatePrev();
|
2757 | }
|
2758 | }
|
2759 |
|
2760 | if (handled) {
|
2761 |
|
2762 | e.stopPropagation();
|
2763 | e.preventDefault();
|
2764 | try {
|
2765 | e.originalEvent.keyCode = 0;
|
2766 | }
|
2767 |
|
2768 |
|
2769 | catch (error) {
|
2770 | }
|
2771 | }
|
2772 | }
|
2773 |
|
2774 | function handleClick(e) {
|
2775 | if (!currentEditor) {
|
2776 |
|
2777 |
|
2778 |
|
2779 | if (e.target != document.activeElement || $(e.target).hasClass("slick-cell")) {
|
2780 | setFocus();
|
2781 | }
|
2782 | }
|
2783 |
|
2784 | var cell = getCellFromEvent(e);
|
2785 | if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)) {
|
2786 | return;
|
2787 | }
|
2788 |
|
2789 | trigger(self.onClick, {row: cell.row, cell: cell.cell}, e);
|
2790 | if (e.isImmediatePropagationStopped()) {
|
2791 | return;
|
2792 | }
|
2793 |
|
2794 |
|
2795 |
|
2796 | if (canCellBeActive(cell.row, cell.cell)) {
|
2797 | if (!getEditorLock().isActive() || getEditorLock().commitCurrentEdit()) {
|
2798 | scrollRowIntoView(cell.row, false);
|
2799 |
|
2800 | var preClickModeOn = (e.target && e.target.className === Slick.preClickClassName);
|
2801 | var column = columns[cell.cell];
|
2802 | var suppressActiveCellChangedEvent = (options.editable && column && column.editor && options.suppressActiveCellChangeOnEdit) ? true : false;
|
2803 | setActiveCellInternal(getCellNode(cell.row, cell.cell), null, preClickModeOn, suppressActiveCellChangedEvent);
|
2804 | }
|
2805 | }
|
2806 | }
|
2807 |
|
2808 | function handleContextMenu(e) {
|
2809 | var $cell = $(e.target).closest(".slick-cell", $canvas);
|
2810 | if ($cell.length === 0) {
|
2811 | return;
|
2812 | }
|
2813 |
|
2814 |
|
2815 | if (activeCellNode === $cell[0] && currentEditor !== null) {
|
2816 | return;
|
2817 | }
|
2818 |
|
2819 | trigger(self.onContextMenu, {}, e);
|
2820 | }
|
2821 |
|
2822 | function handleDblClick(e) {
|
2823 | var cell = getCellFromEvent(e);
|
2824 | if (!cell || (currentEditor !== null && activeRow == cell.row && activeCell == cell.cell)) {
|
2825 | return;
|
2826 | }
|
2827 |
|
2828 | trigger(self.onDblClick, {row: cell.row, cell: cell.cell}, e);
|
2829 | if (e.isImmediatePropagationStopped()) {
|
2830 | return;
|
2831 | }
|
2832 |
|
2833 | if (options.editable) {
|
2834 | gotoCell(cell.row, cell.cell, true);
|
2835 | }
|
2836 | }
|
2837 |
|
2838 | function handleHeaderMouseEnter(e) {
|
2839 | trigger(self.onHeaderMouseEnter, {
|
2840 | "column": $(this).data("column"),
|
2841 | "grid": self
|
2842 | }, e);
|
2843 | }
|
2844 |
|
2845 | function handleHeaderMouseLeave(e) {
|
2846 | trigger(self.onHeaderMouseLeave, {
|
2847 | "column": $(this).data("column"),
|
2848 | "grid": self
|
2849 | }, e);
|
2850 | }
|
2851 |
|
2852 | function handleHeaderContextMenu(e) {
|
2853 | var $header = $(e.target).closest(".slick-header-column", ".slick-header-columns");
|
2854 | var column = $header && $header.data("column");
|
2855 | trigger(self.onHeaderContextMenu, {column: column}, e);
|
2856 | }
|
2857 |
|
2858 | function handleHeaderClick(e) {
|
2859 | if (columnResizeDragging) return;
|
2860 | var $header = $(e.target).closest(".slick-header-column", ".slick-header-columns");
|
2861 | var column = $header && $header.data("column");
|
2862 | if (column) {
|
2863 | trigger(self.onHeaderClick, {column: column}, e);
|
2864 | }
|
2865 | }
|
2866 |
|
2867 | function handleMouseEnter(e) {
|
2868 | trigger(self.onMouseEnter, {}, e);
|
2869 | }
|
2870 |
|
2871 | function handleMouseLeave(e) {
|
2872 | trigger(self.onMouseLeave, {}, e);
|
2873 | }
|
2874 |
|
2875 | function cellExists(row, cell) {
|
2876 | return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length);
|
2877 | }
|
2878 |
|
2879 | function getCellFromPoint(x, y) {
|
2880 | var row = getRowFromPosition(y);
|
2881 | var cell = 0;
|
2882 |
|
2883 | var w = 0;
|
2884 | for (var i = 0; i < columns.length && w < x; i++) {
|
2885 | w += columns[i].width;
|
2886 | cell++;
|
2887 | }
|
2888 |
|
2889 | if (cell < 0) {
|
2890 | cell = 0;
|
2891 | }
|
2892 |
|
2893 | return {row: row, cell: cell - 1};
|
2894 | }
|
2895 |
|
2896 | function getCellFromNode(cellNode) {
|
2897 |
|
2898 | var cls = /l\d+/.exec(cellNode.className);
|
2899 | if (!cls) {
|
2900 | throw new Error("getCellFromNode: cannot get cell - " + cellNode.className);
|
2901 | }
|
2902 | return parseInt(cls[0].substr(1, cls[0].length - 1), 10);
|
2903 | }
|
2904 |
|
2905 | function getRowFromNode(rowNode) {
|
2906 | for (var row in rowsCache) {
|
2907 | if (rowsCache[row].rowNode === rowNode) {
|
2908 | return row | 0;
|
2909 | }
|
2910 | }
|
2911 |
|
2912 | return null;
|
2913 | }
|
2914 |
|
2915 | function getCellFromEvent(e) {
|
2916 | var $cell = $(e.target).closest(".slick-cell", $canvas);
|
2917 | if (!$cell.length) {
|
2918 | return null;
|
2919 | }
|
2920 |
|
2921 | var row = getRowFromNode($cell[0].parentNode);
|
2922 | var cell = getCellFromNode($cell[0]);
|
2923 |
|
2924 | if (row == null || cell == null) {
|
2925 | return null;
|
2926 | } else {
|
2927 | return {
|
2928 | "row": row,
|
2929 | "cell": cell
|
2930 | };
|
2931 | }
|
2932 | }
|
2933 |
|
2934 | function getCellNodeBox(row, cell) {
|
2935 | if (!cellExists(row, cell)) {
|
2936 | return null;
|
2937 | }
|
2938 |
|
2939 | var y1 = getRowTop(row);
|
2940 | var y2 = y1 + options.rowHeight - 1;
|
2941 | var x1 = 0;
|
2942 | for (var i = 0; i < cell; i++) {
|
2943 | x1 += columns[i].width;
|
2944 | }
|
2945 | var x2 = x1 + columns[cell].width;
|
2946 |
|
2947 | return {
|
2948 | top: y1,
|
2949 | left: x1,
|
2950 | bottom: y2,
|
2951 | right: x2
|
2952 | };
|
2953 | }
|
2954 |
|
2955 |
|
2956 |
|
2957 |
|
2958 | function resetActiveCell() {
|
2959 | setActiveCellInternal(null, false);
|
2960 | }
|
2961 |
|
2962 | function setFocus() {
|
2963 | if (tabbingDirection == -1) {
|
2964 | $focusSink[0].focus();
|
2965 | } else {
|
2966 | $focusSink2[0].focus();
|
2967 | }
|
2968 | }
|
2969 |
|
2970 | function scrollCellIntoView(row, cell, doPaging) {
|
2971 | scrollRowIntoView(row, doPaging);
|
2972 |
|
2973 | var colspan = getColspan(row, cell);
|
2974 | internalScrollColumnIntoView(columnPosLeft[cell], columnPosRight[cell + (colspan > 1 ? colspan - 1 : 0)]);
|
2975 | }
|
2976 |
|
2977 | function internalScrollColumnIntoView(left, right) {
|
2978 | var scrollRight = scrollLeft + viewportW;
|
2979 |
|
2980 | if (left < scrollLeft) {
|
2981 | $viewport.scrollLeft(left);
|
2982 | handleScroll();
|
2983 | render();
|
2984 | } else if (right > scrollRight) {
|
2985 | $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth));
|
2986 | handleScroll();
|
2987 | render();
|
2988 | }
|
2989 | }
|
2990 |
|
2991 | function scrollColumnIntoView(cell) {
|
2992 | internalScrollColumnIntoView(columnPosLeft[cell], columnPosRight[cell]);
|
2993 | }
|
2994 |
|
2995 | function setActiveCellInternal(newCell, opt_editMode, preClickModeOn, suppressActiveCellChangedEvent) {
|
2996 | if (activeCellNode !== null) {
|
2997 | makeActiveCellNormal();
|
2998 | $(activeCellNode).removeClass("active");
|
2999 | if (rowsCache[activeRow]) {
|
3000 | $(rowsCache[activeRow].rowNode).removeClass("active");
|
3001 | }
|
3002 | }
|
3003 |
|
3004 | var activeCellChanged = (activeCellNode !== newCell);
|
3005 | activeCellNode = newCell;
|
3006 |
|
3007 | if (activeCellNode != null) {
|
3008 | activeRow = getRowFromNode(activeCellNode.parentNode);
|
3009 | activeCell = activePosX = getCellFromNode(activeCellNode);
|
3010 |
|
3011 | if (opt_editMode == null) {
|
3012 | opt_editMode = (activeRow == getDataLength()) || options.autoEdit;
|
3013 | }
|
3014 |
|
3015 | if (options.showCellSelection) {
|
3016 | $(activeCellNode).addClass("active");
|
3017 | $(rowsCache[activeRow].rowNode).addClass("active");
|
3018 | }
|
3019 |
|
3020 | if (options.editable && opt_editMode && isCellPotentiallyEditable(activeRow, activeCell)) {
|
3021 | clearTimeout(h_editorLoader);
|
3022 |
|
3023 | if (options.asyncEditorLoading) {
|
3024 | h_editorLoader = setTimeout(function () {
|
3025 | makeActiveCellEditable(undefined, preClickModeOn);
|
3026 | }, options.asyncEditorLoadDelay);
|
3027 | } else {
|
3028 | makeActiveCellEditable(undefined, preClickModeOn);
|
3029 | }
|
3030 | }
|
3031 | } else {
|
3032 | activeRow = activeCell = null;
|
3033 | }
|
3034 |
|
3035 |
|
3036 |
|
3037 | if (!suppressActiveCellChangedEvent) { trigger(self.onActiveCellChanged, getActiveCell()); }
|
3038 |
|
3039 | }
|
3040 |
|
3041 | function clearTextSelection() {
|
3042 | if (document.selection && document.selection.empty) {
|
3043 | try {
|
3044 |
|
3045 | document.selection.empty();
|
3046 | } catch (e) { }
|
3047 | } else if (window.getSelection) {
|
3048 | var sel = window.getSelection();
|
3049 | if (sel && sel.removeAllRanges) {
|
3050 | sel.removeAllRanges();
|
3051 | }
|
3052 | }
|
3053 | }
|
3054 |
|
3055 | function isCellPotentiallyEditable(row, cell) {
|
3056 | var dataLength = getDataLength();
|
3057 |
|
3058 | if (row < dataLength && !getDataItem(row)) {
|
3059 | return false;
|
3060 | }
|
3061 |
|
3062 |
|
3063 | if (columns[cell].cannotTriggerInsert && row >= dataLength) {
|
3064 | return false;
|
3065 | }
|
3066 |
|
3067 |
|
3068 | if (!getEditor(row, cell)) {
|
3069 | return false;
|
3070 | }
|
3071 |
|
3072 | return true;
|
3073 | }
|
3074 |
|
3075 | function makeActiveCellNormal() {
|
3076 | if (!currentEditor) {
|
3077 | return;
|
3078 | }
|
3079 | trigger(self.onBeforeCellEditorDestroy, {editor: currentEditor});
|
3080 | currentEditor.destroy();
|
3081 | currentEditor = null;
|
3082 |
|
3083 | if (activeCellNode) {
|
3084 | var d = getDataItem(activeRow);
|
3085 | $(activeCellNode).removeClass("editable invalid");
|
3086 | if (d) {
|
3087 | var column = columns[activeCell];
|
3088 | var formatter = getFormatter(activeRow, column);
|
3089 | var formatterResult = formatter(activeRow, activeCell, getDataItemValueForColumn(d, column), column, d, self);
|
3090 | applyFormatResultToCellNode(formatterResult, activeCellNode);
|
3091 | invalidatePostProcessingResults(activeRow);
|
3092 | }
|
3093 | }
|
3094 |
|
3095 |
|
3096 |
|
3097 | if (navigator.userAgent.toLowerCase().match(/msie/)) {
|
3098 | clearTextSelection();
|
3099 | }
|
3100 |
|
3101 | getEditorLock().deactivate(editController);
|
3102 | }
|
3103 |
|
3104 | function makeActiveCellEditable(editor, preClickModeOn) {
|
3105 | if (!activeCellNode) {
|
3106 | return;
|
3107 | }
|
3108 | if (!options.editable) {
|
3109 | throw new Error("Grid : makeActiveCellEditable : should never get called when options.editable is false");
|
3110 | }
|
3111 |
|
3112 |
|
3113 | clearTimeout(h_editorLoader);
|
3114 |
|
3115 | if (!isCellPotentiallyEditable(activeRow, activeCell)) {
|
3116 | return;
|
3117 | }
|
3118 |
|
3119 | var columnDef = columns[activeCell];
|
3120 | var item = getDataItem(activeRow);
|
3121 |
|
3122 | if (trigger(self.onBeforeEditCell, {row: activeRow, cell: activeCell, item: item, column: columnDef}) === false) {
|
3123 | setFocus();
|
3124 | return;
|
3125 | }
|
3126 |
|
3127 | getEditorLock().activate(editController);
|
3128 | $(activeCellNode).addClass("editable");
|
3129 |
|
3130 | var useEditor = editor || getEditor(activeRow, activeCell);
|
3131 |
|
3132 |
|
3133 | if (!editor && !useEditor.suppressClearOnEdit) {
|
3134 | activeCellNode.innerHTML = "";
|
3135 | }
|
3136 |
|
3137 | currentEditor = new useEditor({
|
3138 | grid: self,
|
3139 | gridPosition: absBox($container[0]),
|
3140 | position: absBox(activeCellNode),
|
3141 | container: activeCellNode,
|
3142 | column: columnDef,
|
3143 | item: item || {},
|
3144 | commitChanges: commitEditAndSetFocus,
|
3145 | cancelChanges: cancelEditAndSetFocus
|
3146 | });
|
3147 |
|
3148 | if (item) {
|
3149 | currentEditor.loadValue(item);
|
3150 | if (preClickModeOn && currentEditor.preClick) {
|
3151 | currentEditor.preClick();
|
3152 | }
|
3153 | }
|
3154 |
|
3155 | serializedEditorValue = currentEditor.serializeValue();
|
3156 |
|
3157 | if (currentEditor.position) {
|
3158 | handleActiveCellPositionChange();
|
3159 | }
|
3160 | }
|
3161 |
|
3162 | function commitEditAndSetFocus() {
|
3163 |
|
3164 |
|
3165 | if (getEditorLock().commitCurrentEdit()) {
|
3166 | setFocus();
|
3167 | if (options.autoEdit) {
|
3168 | navigateDown();
|
3169 | }
|
3170 | }
|
3171 | }
|
3172 |
|
3173 | function cancelEditAndSetFocus() {
|
3174 | if (getEditorLock().cancelCurrentEdit()) {
|
3175 | setFocus();
|
3176 | }
|
3177 | }
|
3178 |
|
3179 | function absBox(elem) {
|
3180 | var box = {
|
3181 | top: elem.offsetTop,
|
3182 | left: elem.offsetLeft,
|
3183 | bottom: 0,
|
3184 | right: 0,
|
3185 | width: $(elem).outerWidth(),
|
3186 | height: $(elem).outerHeight(),
|
3187 | visible: true};
|
3188 | box.bottom = box.top + box.height;
|
3189 | box.right = box.left + box.width;
|
3190 |
|
3191 |
|
3192 | var offsetParent = elem.offsetParent;
|
3193 | while ((elem = elem.parentNode) != document.body) {
|
3194 | if (elem == null) break;
|
3195 |
|
3196 | if (box.visible && elem.scrollHeight != elem.offsetHeight && $(elem).css("overflowY") != "visible") {
|
3197 | box.visible = box.bottom > elem.scrollTop && box.top < elem.scrollTop + elem.clientHeight;
|
3198 | }
|
3199 |
|
3200 | if (box.visible && elem.scrollWidth != elem.offsetWidth && $(elem).css("overflowX") != "visible") {
|
3201 | box.visible = box.right > elem.scrollLeft && box.left < elem.scrollLeft + elem.clientWidth;
|
3202 | }
|
3203 |
|
3204 | box.left -= elem.scrollLeft;
|
3205 | box.top -= elem.scrollTop;
|
3206 |
|
3207 | if (elem === offsetParent) {
|
3208 | box.left += elem.offsetLeft;
|
3209 | box.top += elem.offsetTop;
|
3210 | offsetParent = elem.offsetParent;
|
3211 | }
|
3212 |
|
3213 | box.bottom = box.top + box.height;
|
3214 | box.right = box.left + box.width;
|
3215 | }
|
3216 |
|
3217 | return box;
|
3218 | }
|
3219 |
|
3220 | function getActiveCellPosition() {
|
3221 | return absBox(activeCellNode);
|
3222 | }
|
3223 |
|
3224 | function getGridPosition() {
|
3225 | return absBox($container[0])
|
3226 | }
|
3227 |
|
3228 | function handleActiveCellPositionChange() {
|
3229 | if (!activeCellNode) {
|
3230 | return;
|
3231 | }
|
3232 |
|
3233 | trigger(self.onActiveCellPositionChanged, {});
|
3234 |
|
3235 | if (currentEditor) {
|
3236 | var cellBox = getActiveCellPosition();
|
3237 | if (currentEditor.show && currentEditor.hide) {
|
3238 | if (!cellBox.visible) {
|
3239 | currentEditor.hide();
|
3240 | } else {
|
3241 | currentEditor.show();
|
3242 | }
|
3243 | }
|
3244 |
|
3245 | if (currentEditor.position) {
|
3246 | currentEditor.position(cellBox);
|
3247 | }
|
3248 | }
|
3249 | }
|
3250 |
|
3251 | function getCellEditor() {
|
3252 | return currentEditor;
|
3253 | }
|
3254 |
|
3255 | function getActiveCell() {
|
3256 | if (!activeCellNode) {
|
3257 | return null;
|
3258 | } else {
|
3259 | return {row: activeRow, cell: activeCell};
|
3260 | }
|
3261 | }
|
3262 |
|
3263 | function getActiveCellNode() {
|
3264 | return activeCellNode;
|
3265 | }
|
3266 |
|
3267 | function scrollRowIntoView(row, doPaging) {
|
3268 | var rowAtTop = row * options.rowHeight;
|
3269 | var rowAtBottom = (row + 1) * options.rowHeight - viewportH + (viewportHasHScroll ? scrollbarDimensions.height : 0);
|
3270 |
|
3271 |
|
3272 | if ((row + 1) * options.rowHeight > scrollTop + viewportH + offset) {
|
3273 | scrollTo(doPaging ? rowAtTop : rowAtBottom);
|
3274 | render();
|
3275 | }
|
3276 |
|
3277 | else if (row * options.rowHeight < scrollTop + offset) {
|
3278 | scrollTo(doPaging ? rowAtBottom : rowAtTop);
|
3279 | render();
|
3280 | }
|
3281 | }
|
3282 |
|
3283 | function scrollRowToTop(row) {
|
3284 | scrollTo(row * options.rowHeight);
|
3285 | render();
|
3286 | }
|
3287 |
|
3288 | function scrollPage(dir) {
|
3289 | var deltaRows = dir * numVisibleRows;
|
3290 | scrollTo((getRowFromPosition(scrollTop) + deltaRows) * options.rowHeight);
|
3291 | render();
|
3292 |
|
3293 | if (options.enableCellNavigation && activeRow != null) {
|
3294 | var row = activeRow + deltaRows;
|
3295 | var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();
|
3296 | if (row >= dataLengthIncludingAddNew) {
|
3297 | row = dataLengthIncludingAddNew - 1;
|
3298 | }
|
3299 | if (row < 0) {
|
3300 | row = 0;
|
3301 | }
|
3302 |
|
3303 | var cell = 0, prevCell = null;
|
3304 | var prevActivePosX = activePosX;
|
3305 | while (cell <= activePosX) {
|
3306 | if (canCellBeActive(row, cell)) {
|
3307 | prevCell = cell;
|
3308 | }
|
3309 | cell += getColspan(row, cell);
|
3310 | }
|
3311 |
|
3312 | if (prevCell !== null) {
|
3313 | setActiveCellInternal(getCellNode(row, prevCell));
|
3314 | activePosX = prevActivePosX;
|
3315 | } else {
|
3316 | resetActiveCell();
|
3317 | }
|
3318 | }
|
3319 | }
|
3320 |
|
3321 | function navigatePageDown() {
|
3322 | scrollPage(1);
|
3323 | }
|
3324 |
|
3325 | function navigatePageUp() {
|
3326 | scrollPage(-1);
|
3327 | }
|
3328 |
|
3329 | function navigateTop() {
|
3330 | navigateToRow(0);
|
3331 | }
|
3332 |
|
3333 | function navigateBottom() {
|
3334 | navigateToRow(getDataLength()-1);
|
3335 | }
|
3336 |
|
3337 | function navigateToRow(row) {
|
3338 | var num_rows = getDataLength();
|
3339 | if (!num_rows) return true;
|
3340 |
|
3341 | if (row < 0) row = 0;
|
3342 | else if (row >= num_rows) row = num_rows - 1;
|
3343 |
|
3344 | scrollCellIntoView(row, 0, true);
|
3345 | if (options.enableCellNavigation && activeRow != null) {
|
3346 | var cell = 0, prevCell = null;
|
3347 | var prevActivePosX = activePosX;
|
3348 | while (cell <= activePosX) {
|
3349 | if (canCellBeActive(row, cell)) {
|
3350 | prevCell = cell;
|
3351 | }
|
3352 | cell += getColspan(row, cell);
|
3353 | }
|
3354 |
|
3355 | if (prevCell !== null) {
|
3356 | setActiveCellInternal(getCellNode(row, prevCell));
|
3357 | activePosX = prevActivePosX;
|
3358 | } else {
|
3359 | resetActiveCell();
|
3360 | }
|
3361 | }
|
3362 | return true;
|
3363 | }
|
3364 |
|
3365 | function getColspan(row, cell) {
|
3366 | var metadata = data.getItemMetadata && data.getItemMetadata(row);
|
3367 | if (!metadata || !metadata.columns) {
|
3368 | return 1;
|
3369 | }
|
3370 |
|
3371 | var columnData = metadata.columns[columns[cell].id] || metadata.columns[cell];
|
3372 | var colspan = (columnData && columnData.colspan);
|
3373 | if (colspan === "*") {
|
3374 | colspan = columns.length - cell;
|
3375 | } else {
|
3376 | colspan = colspan || 1;
|
3377 | }
|
3378 |
|
3379 | return colspan;
|
3380 | }
|
3381 |
|
3382 | function findFirstFocusableCell(row) {
|
3383 | var cell = 0;
|
3384 | while (cell < columns.length) {
|
3385 | if (canCellBeActive(row, cell)) {
|
3386 | return cell;
|
3387 | }
|
3388 | cell += getColspan(row, cell);
|
3389 | }
|
3390 | return null;
|
3391 | }
|
3392 |
|
3393 | function findLastFocusableCell(row) {
|
3394 | var cell = 0;
|
3395 | var lastFocusableCell = null;
|
3396 | while (cell < columns.length) {
|
3397 | if (canCellBeActive(row, cell)) {
|
3398 | lastFocusableCell = cell;
|
3399 | }
|
3400 | cell += getColspan(row, cell);
|
3401 | }
|
3402 | return lastFocusableCell;
|
3403 | }
|
3404 |
|
3405 | function gotoRight(row, cell, posX) {
|
3406 | if (cell >= columns.length) {
|
3407 | return null;
|
3408 | }
|
3409 |
|
3410 | do {
|
3411 | cell += getColspan(row, cell);
|
3412 | }
|
3413 | while (cell < columns.length && !canCellBeActive(row, cell));
|
3414 |
|
3415 | if (cell < columns.length) {
|
3416 | return {
|
3417 | "row": row,
|
3418 | "cell": cell,
|
3419 | "posX": cell
|
3420 | };
|
3421 | }
|
3422 | return null;
|
3423 | }
|
3424 |
|
3425 | function gotoLeft(row, cell, posX) {
|
3426 | if (cell <= 0) {
|
3427 | return null;
|
3428 | }
|
3429 |
|
3430 | var firstFocusableCell = findFirstFocusableCell(row);
|
3431 | if (firstFocusableCell === null || firstFocusableCell >= cell) {
|
3432 | return null;
|
3433 | }
|
3434 |
|
3435 | var prev = {
|
3436 | "row": row,
|
3437 | "cell": firstFocusableCell,
|
3438 | "posX": firstFocusableCell
|
3439 | };
|
3440 | var pos;
|
3441 | while (true) {
|
3442 | pos = gotoRight(prev.row, prev.cell, prev.posX);
|
3443 | if (!pos) {
|
3444 | return null;
|
3445 | }
|
3446 | if (pos.cell >= cell) {
|
3447 | return prev;
|
3448 | }
|
3449 | prev = pos;
|
3450 | }
|
3451 | }
|
3452 |
|
3453 | function gotoDown(row, cell, posX) {
|
3454 | var prevCell;
|
3455 | var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();
|
3456 | while (true) {
|
3457 | if (++row >= dataLengthIncludingAddNew) {
|
3458 | return null;
|
3459 | }
|
3460 |
|
3461 | prevCell = cell = 0;
|
3462 | while (cell <= posX) {
|
3463 | prevCell = cell;
|
3464 | cell += getColspan(row, cell);
|
3465 | }
|
3466 |
|
3467 | if (canCellBeActive(row, prevCell)) {
|
3468 | return {
|
3469 | "row": row,
|
3470 | "cell": prevCell,
|
3471 | "posX": posX
|
3472 | };
|
3473 | }
|
3474 | }
|
3475 | }
|
3476 |
|
3477 | function gotoUp(row, cell, posX) {
|
3478 | var prevCell;
|
3479 | while (true) {
|
3480 | if (--row < 0) {
|
3481 | return null;
|
3482 | }
|
3483 |
|
3484 | prevCell = cell = 0;
|
3485 | while (cell <= posX) {
|
3486 | prevCell = cell;
|
3487 | cell += getColspan(row, cell);
|
3488 | }
|
3489 |
|
3490 | if (canCellBeActive(row, prevCell)) {
|
3491 | return {
|
3492 | "row": row,
|
3493 | "cell": prevCell,
|
3494 | "posX": posX
|
3495 | };
|
3496 | }
|
3497 | }
|
3498 | }
|
3499 |
|
3500 | function gotoNext(row, cell, posX) {
|
3501 | if (row == null && cell == null) {
|
3502 | row = cell = posX = 0;
|
3503 | if (canCellBeActive(row, cell)) {
|
3504 | return {
|
3505 | "row": row,
|
3506 | "cell": cell,
|
3507 | "posX": cell
|
3508 | };
|
3509 | }
|
3510 | }
|
3511 |
|
3512 | var pos = gotoRight(row, cell, posX);
|
3513 | if (pos) {
|
3514 | return pos;
|
3515 | }
|
3516 |
|
3517 | var firstFocusableCell = null;
|
3518 | var dataLengthIncludingAddNew = getDataLengthIncludingAddNew();
|
3519 |
|
3520 |
|
3521 | if (row === dataLengthIncludingAddNew - 1) { row--; }
|
3522 |
|
3523 | while (++row < dataLengthIncludingAddNew) {
|
3524 | firstFocusableCell = findFirstFocusableCell(row);
|
3525 | if (firstFocusableCell !== null) {
|
3526 | return {
|
3527 | "row": row,
|
3528 | "cell": firstFocusableCell,
|
3529 | "posX": firstFocusableCell
|
3530 | };
|
3531 | }
|
3532 | }
|
3533 | return null;
|
3534 | }
|
3535 |
|
3536 | function gotoPrev(row, cell, posX) {
|
3537 | if (row == null && cell == null) {
|
3538 | row = getDataLengthIncludingAddNew() - 1;
|
3539 | cell = posX = columns.length - 1;
|
3540 | if (canCellBeActive(row, cell)) {
|
3541 | return {
|
3542 | "row": row,
|
3543 | "cell": cell,
|
3544 | "posX": cell
|
3545 | };
|
3546 | }
|
3547 | }
|
3548 |
|
3549 | var pos;
|
3550 | var lastSelectableCell;
|
3551 | while (!pos) {
|
3552 | pos = gotoLeft(row, cell, posX);
|
3553 | if (pos) {
|
3554 | break;
|
3555 | }
|
3556 | if (--row < 0) {
|
3557 | return null;
|
3558 | }
|
3559 |
|
3560 | cell = 0;
|
3561 | lastSelectableCell = findLastFocusableCell(row);
|
3562 | if (lastSelectableCell !== null) {
|
3563 | pos = {
|
3564 | "row": row,
|
3565 | "cell": lastSelectableCell,
|
3566 | "posX": lastSelectableCell
|
3567 | };
|
3568 | }
|
3569 | }
|
3570 | return pos;
|
3571 | }
|
3572 |
|
3573 | function gotoRowStart(row, cell, posX) {
|
3574 | var newCell = findFirstFocusableCell(row);
|
3575 | if (newCell === null) return null;
|
3576 |
|
3577 | return {
|
3578 | "row": row,
|
3579 | "cell": newCell,
|
3580 | "posX": newCell
|
3581 | };
|
3582 | }
|
3583 |
|
3584 | function gotoRowEnd(row, cell, posX) {
|
3585 | var newCell = findLastFocusableCell(row);
|
3586 | if (newCell === null) return null;
|
3587 |
|
3588 | return {
|
3589 | "row": row,
|
3590 | "cell": newCell,
|
3591 | "posX": newCell
|
3592 | };
|
3593 | }
|
3594 |
|
3595 | function navigateRight() {
|
3596 | return navigate("right");
|
3597 | }
|
3598 |
|
3599 | function navigateLeft() {
|
3600 | return navigate("left");
|
3601 | }
|
3602 |
|
3603 | function navigateDown() {
|
3604 | return navigate("down");
|
3605 | }
|
3606 |
|
3607 | function navigateUp() {
|
3608 | return navigate("up");
|
3609 | }
|
3610 |
|
3611 | function navigateNext() {
|
3612 | return navigate("next");
|
3613 | }
|
3614 |
|
3615 | function navigatePrev() {
|
3616 | return navigate("prev");
|
3617 | }
|
3618 |
|
3619 | function navigateRowStart() {
|
3620 | return navigate("home");
|
3621 | }
|
3622 |
|
3623 | function navigateRowEnd() {
|
3624 | return navigate("end");
|
3625 | }
|
3626 |
|
3627 | |
3628 |
|
3629 |
|
3630 |
|
3631 | function navigate(dir) {
|
3632 | if (!options.enableCellNavigation) {
|
3633 | return false;
|
3634 | }
|
3635 |
|
3636 | if (!activeCellNode && dir != "prev" && dir != "next") {
|
3637 | return false;
|
3638 | }
|
3639 |
|
3640 | if (!getEditorLock().commitCurrentEdit()) {
|
3641 | return true;
|
3642 | }
|
3643 | setFocus();
|
3644 |
|
3645 | var tabbingDirections = {
|
3646 | "up": -1,
|
3647 | "down": 1,
|
3648 | "left": -1,
|
3649 | "right": 1,
|
3650 | "prev": -1,
|
3651 | "next": 1,
|
3652 | "home": -1,
|
3653 | "end": 1
|
3654 | };
|
3655 | tabbingDirection = tabbingDirections[dir];
|
3656 |
|
3657 | var stepFunctions = {
|
3658 | "up": gotoUp,
|
3659 | "down": gotoDown,
|
3660 | "left": gotoLeft,
|
3661 | "right": gotoRight,
|
3662 | "prev": gotoPrev,
|
3663 | "next": gotoNext,
|
3664 | "home": gotoRowStart,
|
3665 | "end": gotoRowEnd
|
3666 | };
|
3667 | var stepFn = stepFunctions[dir];
|
3668 | var pos = stepFn(activeRow, activeCell, activePosX);
|
3669 | if (pos) {
|
3670 | var isAddNewRow = (pos.row == getDataLength());
|
3671 | scrollCellIntoView(pos.row, pos.cell, !isAddNewRow && options.emulatePagingWhenScrolling);
|
3672 | setActiveCellInternal(getCellNode(pos.row, pos.cell));
|
3673 | activePosX = pos.posX;
|
3674 | return true;
|
3675 | } else {
|
3676 | setActiveCellInternal(getCellNode(activeRow, activeCell));
|
3677 | return false;
|
3678 | }
|
3679 | }
|
3680 |
|
3681 | function getCellNode(row, cell) {
|
3682 | if (rowsCache[row]) {
|
3683 | ensureCellNodesInRowsCache(row);
|
3684 | return rowsCache[row].cellNodesByColumnIdx[cell];
|
3685 | }
|
3686 | return null;
|
3687 | }
|
3688 |
|
3689 | function setActiveCell(row, cell, opt_editMode, preClickModeOn, suppressActiveCellChangedEvent) {
|
3690 | if (!initialized) { return; }
|
3691 | if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) {
|
3692 | return;
|
3693 | }
|
3694 |
|
3695 | if (!options.enableCellNavigation) {
|
3696 | return;
|
3697 | }
|
3698 |
|
3699 | scrollCellIntoView(row, cell, false);
|
3700 | setActiveCellInternal(getCellNode(row, cell), opt_editMode, preClickModeOn, suppressActiveCellChangedEvent);
|
3701 | }
|
3702 |
|
3703 | function canCellBeActive(row, cell) {
|
3704 | if (!options.enableCellNavigation || row >= getDataLengthIncludingAddNew() ||
|
3705 | row < 0 || cell >= columns.length || cell < 0) {
|
3706 | return false;
|
3707 | }
|
3708 |
|
3709 | var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);
|
3710 | if (rowMetadata && typeof rowMetadata.focusable !== "undefined") {
|
3711 | return !!rowMetadata.focusable;
|
3712 | }
|
3713 |
|
3714 | var columnMetadata = rowMetadata && rowMetadata.columns;
|
3715 | if (columnMetadata && columnMetadata[columns[cell].id] && typeof columnMetadata[columns[cell].id].focusable !== "undefined") {
|
3716 | return !!columnMetadata[columns[cell].id].focusable;
|
3717 | }
|
3718 | if (columnMetadata && columnMetadata[cell] && typeof columnMetadata[cell].focusable !== "undefined") {
|
3719 | return !!columnMetadata[cell].focusable;
|
3720 | }
|
3721 |
|
3722 | return !!columns[cell].focusable;
|
3723 | }
|
3724 |
|
3725 | function canCellBeSelected(row, cell) {
|
3726 | if (row >= getDataLength() || row < 0 || cell >= columns.length || cell < 0) {
|
3727 | return false;
|
3728 | }
|
3729 |
|
3730 | var rowMetadata = data.getItemMetadata && data.getItemMetadata(row);
|
3731 | if (rowMetadata && typeof rowMetadata.selectable !== "undefined") {
|
3732 | return !!rowMetadata.selectable;
|
3733 | }
|
3734 |
|
3735 | var columnMetadata = rowMetadata && rowMetadata.columns && (rowMetadata.columns[columns[cell].id] || rowMetadata.columns[cell]);
|
3736 | if (columnMetadata && typeof columnMetadata.selectable !== "undefined") {
|
3737 | return !!columnMetadata.selectable;
|
3738 | }
|
3739 |
|
3740 | return !!columns[cell].selectable;
|
3741 | }
|
3742 |
|
3743 | function gotoCell(row, cell, forceEdit) {
|
3744 | if (!initialized) { return; }
|
3745 | if (!canCellBeActive(row, cell)) {
|
3746 | return;
|
3747 | }
|
3748 |
|
3749 | if (!getEditorLock().commitCurrentEdit()) {
|
3750 | return;
|
3751 | }
|
3752 |
|
3753 | scrollCellIntoView(row, cell, false);
|
3754 |
|
3755 | var newCell = getCellNode(row, cell);
|
3756 |
|
3757 |
|
3758 | setActiveCellInternal(newCell, (forceEdit || (row === getDataLength()) || options.autoEdit), null, options.editable);
|
3759 |
|
3760 |
|
3761 | if (!currentEditor) {
|
3762 | setFocus();
|
3763 | }
|
3764 | }
|
3765 |
|
3766 |
|
3767 |
|
3768 |
|
3769 |
|
3770 | function commitCurrentEdit() {
|
3771 | var item = getDataItem(activeRow);
|
3772 | var column = columns[activeCell];
|
3773 |
|
3774 | if (currentEditor) {
|
3775 | if (currentEditor.isValueChanged()) {
|
3776 | var validationResults = currentEditor.validate();
|
3777 |
|
3778 | if (validationResults.valid) {
|
3779 | if (activeRow < getDataLength()) {
|
3780 | var editCommand = {
|
3781 | row: activeRow,
|
3782 | cell: activeCell,
|
3783 | editor: currentEditor,
|
3784 | serializedValue: currentEditor.serializeValue(),
|
3785 | prevSerializedValue: serializedEditorValue,
|
3786 | execute: function () {
|
3787 | this.editor.applyValue(item, this.serializedValue);
|
3788 | updateRow(this.row);
|
3789 | trigger(self.onCellChange, {
|
3790 | row: this.row,
|
3791 | cell: this.cell,
|
3792 | item: item
|
3793 | });
|
3794 | },
|
3795 | undo: function () {
|
3796 | this.editor.applyValue(item, this.prevSerializedValue);
|
3797 | updateRow(this.row);
|
3798 | trigger(self.onCellChange, {
|
3799 | row: this.row,
|
3800 | cell: this.cell,
|
3801 | item: item
|
3802 | });
|
3803 | }
|
3804 | };
|
3805 |
|
3806 | if (options.editCommandHandler) {
|
3807 | makeActiveCellNormal();
|
3808 | options.editCommandHandler(item, column, editCommand);
|
3809 | } else {
|
3810 | editCommand.execute();
|
3811 | makeActiveCellNormal();
|
3812 | }
|
3813 |
|
3814 | } else {
|
3815 | var newItem = {};
|
3816 | currentEditor.applyValue(newItem, currentEditor.serializeValue());
|
3817 | makeActiveCellNormal();
|
3818 | trigger(self.onAddNewRow, {item: newItem, column: column});
|
3819 | }
|
3820 |
|
3821 |
|
3822 | return !getEditorLock().isActive();
|
3823 | } else {
|
3824 |
|
3825 | $(activeCellNode).removeClass("invalid");
|
3826 | $(activeCellNode).width();
|
3827 | $(activeCellNode).addClass("invalid");
|
3828 |
|
3829 | trigger(self.onValidationError, {
|
3830 | editor: currentEditor,
|
3831 | cellNode: activeCellNode,
|
3832 | validationResults: validationResults,
|
3833 | row: activeRow,
|
3834 | cell: activeCell,
|
3835 | column: column
|
3836 | });
|
3837 |
|
3838 | currentEditor.focus();
|
3839 | return false;
|
3840 | }
|
3841 | }
|
3842 |
|
3843 | makeActiveCellNormal();
|
3844 | }
|
3845 | return true;
|
3846 | }
|
3847 |
|
3848 | function cancelCurrentEdit() {
|
3849 | makeActiveCellNormal();
|
3850 | return true;
|
3851 | }
|
3852 |
|
3853 | function rowsToRanges(rows) {
|
3854 | var ranges = [];
|
3855 | var lastCell = columns.length - 1;
|
3856 | for (var i = 0; i < rows.length; i++) {
|
3857 | ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell));
|
3858 | }
|
3859 | return ranges;
|
3860 | }
|
3861 |
|
3862 | function getSelectedRows() {
|
3863 | if (!selectionModel) {
|
3864 | throw new Error("Selection model is not set");
|
3865 | }
|
3866 | return selectedRows;
|
3867 | }
|
3868 |
|
3869 | function setSelectedRows(rows) {
|
3870 | if (!selectionModel) {
|
3871 | throw new Error("Selection model is not set");
|
3872 | }
|
3873 | if (!grid.getEditorLock().isActive()) {
|
3874 | selectionModel.setSelectedRanges(rowsToRanges(rows));
|
3875 | }
|
3876 | }
|
3877 |
|
3878 |
|
3879 |
|
3880 |
|
3881 |
|
3882 | this.debug = function () {
|
3883 | var s = "";
|
3884 |
|
3885 | s += ("\n" + "counter_rows_rendered: " + counter_rows_rendered);
|
3886 | s += ("\n" + "counter_rows_removed: " + counter_rows_removed);
|
3887 | s += ("\n" + "renderedRows: " + renderedRows);
|
3888 | s += ("\n" + "numVisibleRows: " + numVisibleRows);
|
3889 | s += ("\n" + "maxSupportedCssHeight: " + maxSupportedCssHeight);
|
3890 | s += ("\n" + "n(umber of pages): " + n);
|
3891 | s += ("\n" + "(current) page: " + page);
|
3892 | s += ("\n" + "page height (ph): " + ph);
|
3893 | s += ("\n" + "vScrollDir: " + vScrollDir);
|
3894 |
|
3895 | alert(s);
|
3896 | };
|
3897 |
|
3898 |
|
3899 | this.eval = function (expr) {
|
3900 | return eval(expr);
|
3901 | };
|
3902 |
|
3903 |
|
3904 |
|
3905 |
|
3906 | $.extend(this, {
|
3907 | "slickGridVersion": "2.3.21",
|
3908 |
|
3909 |
|
3910 | "onScroll": new Slick.Event(),
|
3911 | "onSort": new Slick.Event(),
|
3912 | "onHeaderMouseEnter": new Slick.Event(),
|
3913 | "onHeaderMouseLeave": new Slick.Event(),
|
3914 | "onHeaderContextMenu": new Slick.Event(),
|
3915 | "onHeaderClick": new Slick.Event(),
|
3916 | "onHeaderCellRendered": new Slick.Event(),
|
3917 | "onBeforeHeaderCellDestroy": new Slick.Event(),
|
3918 | "onHeaderRowCellRendered": new Slick.Event(),
|
3919 | "onFooterRowCellRendered": new Slick.Event(),
|
3920 | "onBeforeHeaderRowCellDestroy": new Slick.Event(),
|
3921 | "onBeforeFooterRowCellDestroy": new Slick.Event(),
|
3922 | "onMouseEnter": new Slick.Event(),
|
3923 | "onMouseLeave": new Slick.Event(),
|
3924 | "onClick": new Slick.Event(),
|
3925 | "onDblClick": new Slick.Event(),
|
3926 | "onContextMenu": new Slick.Event(),
|
3927 | "onKeyDown": new Slick.Event(),
|
3928 | "onAddNewRow": new Slick.Event(),
|
3929 | "onBeforeAppendCell": new Slick.Event(),
|
3930 | "onValidationError": new Slick.Event(),
|
3931 | "onViewportChanged": new Slick.Event(),
|
3932 | "onColumnsReordered": new Slick.Event(),
|
3933 | "onColumnsResized": new Slick.Event(),
|
3934 | "onCellChange": new Slick.Event(),
|
3935 | "onBeforeEditCell": new Slick.Event(),
|
3936 | "onBeforeCellEditorDestroy": new Slick.Event(),
|
3937 | "onBeforeDestroy": new Slick.Event(),
|
3938 | "onActiveCellChanged": new Slick.Event(),
|
3939 | "onActiveCellPositionChanged": new Slick.Event(),
|
3940 | "onDragInit": new Slick.Event(),
|
3941 | "onDragStart": new Slick.Event(),
|
3942 | "onDrag": new Slick.Event(),
|
3943 | "onDragEnd": new Slick.Event(),
|
3944 | "onSelectedRowsChanged": new Slick.Event(),
|
3945 | "onCellCssStylesChanged": new Slick.Event(),
|
3946 | "onAutosizeColumns": new Slick.Event(),
|
3947 |
|
3948 |
|
3949 | "registerPlugin": registerPlugin,
|
3950 | "unregisterPlugin": unregisterPlugin,
|
3951 | "getColumns": getColumns,
|
3952 | "setColumns": setColumns,
|
3953 | "getColumnIndex": getColumnIndex,
|
3954 | "updateColumnHeader": updateColumnHeader,
|
3955 | "setSortColumn": setSortColumn,
|
3956 | "setSortColumns": setSortColumns,
|
3957 | "getSortColumns": getSortColumns,
|
3958 | "autosizeColumns": autosizeColumns,
|
3959 | "getOptions": getOptions,
|
3960 | "setOptions": setOptions,
|
3961 | "getData": getData,
|
3962 | "getDataLength": getDataLength,
|
3963 | "getDataItem": getDataItem,
|
3964 | "setData": setData,
|
3965 | "getSelectionModel": getSelectionModel,
|
3966 | "setSelectionModel": setSelectionModel,
|
3967 | "getSelectedRows": getSelectedRows,
|
3968 | "setSelectedRows": setSelectedRows,
|
3969 | "getContainerNode": getContainerNode,
|
3970 | "updatePagingStatusFromView": updatePagingStatusFromView,
|
3971 |
|
3972 | "render": render,
|
3973 | "invalidate": invalidate,
|
3974 | "invalidateRow": invalidateRow,
|
3975 | "invalidateRows": invalidateRows,
|
3976 | "invalidateAllRows": invalidateAllRows,
|
3977 | "updateCell": updateCell,
|
3978 | "updateRow": updateRow,
|
3979 | "getViewport": getVisibleRange,
|
3980 | "getRenderedRange": getRenderedRange,
|
3981 | "resizeCanvas": resizeCanvas,
|
3982 | "updateRowCount": updateRowCount,
|
3983 | "scrollRowIntoView": scrollRowIntoView,
|
3984 | "scrollRowToTop": scrollRowToTop,
|
3985 | "scrollCellIntoView": scrollCellIntoView,
|
3986 | "scrollColumnIntoView": scrollColumnIntoView,
|
3987 | "getCanvasNode": getCanvasNode,
|
3988 | "getUID": getUID,
|
3989 | "getHeaderColumnWidthDiff": getHeaderColumnWidthDiff,
|
3990 | "getScrollbarDimensions": getScrollbarDimensions,
|
3991 | "getHeadersWidth": getHeadersWidth,
|
3992 | "getCanvasWidth": getCanvasWidth,
|
3993 | "focus": setFocus,
|
3994 | "scrollTo": scrollTo,
|
3995 |
|
3996 | "getCellFromPoint": getCellFromPoint,
|
3997 | "getCellFromEvent": getCellFromEvent,
|
3998 | "getActiveCell": getActiveCell,
|
3999 | "setActiveCell": setActiveCell,
|
4000 | "getActiveCellNode": getActiveCellNode,
|
4001 | "getActiveCellPosition": getActiveCellPosition,
|
4002 | "resetActiveCell": resetActiveCell,
|
4003 | "editActiveCell": makeActiveCellEditable,
|
4004 | "getCellEditor": getCellEditor,
|
4005 | "getCellNode": getCellNode,
|
4006 | "getCellNodeBox": getCellNodeBox,
|
4007 | "canCellBeSelected": canCellBeSelected,
|
4008 | "canCellBeActive": canCellBeActive,
|
4009 | "navigatePrev": navigatePrev,
|
4010 | "navigateNext": navigateNext,
|
4011 | "navigateUp": navigateUp,
|
4012 | "navigateDown": navigateDown,
|
4013 | "navigateLeft": navigateLeft,
|
4014 | "navigateRight": navigateRight,
|
4015 | "navigatePageUp": navigatePageUp,
|
4016 | "navigatePageDown": navigatePageDown,
|
4017 | "navigateTop": navigateTop,
|
4018 | "navigateBottom": navigateBottom,
|
4019 | "navigateRowStart": navigateRowStart,
|
4020 | "navigateRowEnd": navigateRowEnd,
|
4021 | "gotoCell": gotoCell,
|
4022 | "getTopPanel": getTopPanel,
|
4023 | "setTopPanelVisibility": setTopPanelVisibility,
|
4024 | "getPreHeaderPanel": getPreHeaderPanel,
|
4025 | "setPreHeaderPanelVisibility": setPreHeaderPanelVisibility,
|
4026 | "getHeader": getHeader,
|
4027 | "getHeaderColumn": getHeaderColumn,
|
4028 | "setHeaderRowVisibility": setHeaderRowVisibility,
|
4029 | "getHeaderRow": getHeaderRow,
|
4030 | "getHeaderRowColumn": getHeaderRowColumn,
|
4031 | "setFooterRowVisibility": setFooterRowVisibility,
|
4032 | "getFooterRow": getFooterRow,
|
4033 | "getFooterRowColumn": getFooterRowColumn,
|
4034 | "getGridPosition": getGridPosition,
|
4035 | "flashCell": flashCell,
|
4036 | "addCellCssStyles": addCellCssStyles,
|
4037 | "setCellCssStyles": setCellCssStyles,
|
4038 | "removeCellCssStyles": removeCellCssStyles,
|
4039 | "getCellCssStyles": getCellCssStyles,
|
4040 |
|
4041 | "init": finishInitialization,
|
4042 | "destroy": destroy,
|
4043 |
|
4044 |
|
4045 | "getEditorLock": getEditorLock,
|
4046 | "getEditController": getEditController
|
4047 | });
|
4048 |
|
4049 | init();
|
4050 | }
|
4051 | }(jQuery));
|